Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: BUG?  I can reproduce "Association request to the driver failed" at will
From: Johannes Berg @ 2009-10-10 18:40 UTC (permalink / raw)
  To: Holger Schurig; +Cc: linux-wireless, hostap
In-Reply-To: <200909211309.40476.hs4233@mail.mn-solutions.de>

[-- Attachment #1: Type: text/plain, Size: 2636 bytes --]

Sorry to warm this up ...

> 1253527140.795498: State: COMPLETED -> AUTHENTICATING
> 1253527140.795515: EAPOL: External notification - EAP success=0
> 1253527140.795530: EAPOL: External notification - EAP fail=0
> 1253527140.795542: EAPOL: External notification - portControl=Auto
> 1253527140.795559: nl80211: Authenticate (ifindex=34)
> 1253527140.795572:   * bssid=00:13:19:80:da:30
> 1253527140.795587:   * freq=2412
> 1253527140.795598:   * SSID - hexdump_ascii(len=5):
>      4d 4e 57 50 41                                    MNWPA
> 1253527140.795630:   * IEs - hexdump(len=0): [NULL]
> 1253527140.795643:   * Auth Type 0
> 1253527140.795683: nl80211: Authentication request send successfully
> 1253527140.795707: RTM_NEWLINK: operstate=1 ifi_flags=0x11043 ([UP][RUNNING][LOWER_UP])
> 1253527140.795725: RTM_NEWLINK, IFLA_IFNAME: Interface 'eth1' added
> 1253527140.953161: nl80211: Event message available
> 1253527140.953200: nl80211: MLME event 37
> 1253527140.953216: SME: Authentication response: peer=00:13:19:80:da:30 auth_type=0 status_code=0
> 1253527140.953243: Trying to associate with 00:13:19:80:da:30 (SSID='MNWPA' freq=2412 MHz)
> 1253527140.953257: State: AUTHENTICATING -> ASSOCIATING
> 1253527140.953270: wpa_driver_nl80211_set_operstate: operstate 1->0 (DORMANT)
> 1253527140.953284: nl80211: Operstate: linkmode=-1, operstate=5
> 1253527140.953901: nl80211: Associate (ifindex=34)
> 1253527140.953919:   * bssid=00:13:19:80:da:30
> 1253527140.953934:   * freq=2412
> 1253527140.953945:   * SSID - hexdump_ascii(len=5):
>      4d 4e 57 50 41                                    MNWPA
> 1253527140.953977:   * IEs - hexdump(len=24): dd 16 00 50 f2 01 01 00 00 50 f2 02 01 00 00 50 f2 02 01 00 00 50 f2 02
> 1253527140.954064: nl80211: MLME command failed: ret=-114 (Operation already in progress)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 1253527140.954086: Association request to the driver failed
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 1253527140.954113: RTM_NEWLINK: operstate=0 ifi_flags=0x11003 ([UP][LOWER_UP])
> 1253527140.954131: RTM_NEWLINK, IFLA_IFNAME: Interface 'eth1' added
> 
> 
> The "Association request to the driver failed" will
> be shown even without "-d". Also note that the association
> seems to actually work, e.g. I can ping throught the
> connection.

Could this be related to the problem Maxim has been seeing? I'm not sure
how else this could happen since you seem to auth but then assoc doesn't
work, but I can't see how that could possibly happen.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: BUG?  I can reproduce "Association request to the driver failed" at will
From: Johannes Berg @ 2009-10-10 18:39 UTC (permalink / raw)
  To: Holger Schurig; +Cc: linux-wireless, hostap
In-Reply-To: <200909211309.40476.hs4233@mail.mn-solutions.de>

[-- Attachment #1: Type: text/plain, Size: 2636 bytes --]

Sorry to warm this up ...

> 1253527140.795498: State: COMPLETED -> AUTHENTICATING
> 1253527140.795515: EAPOL: External notification - EAP success=0
> 1253527140.795530: EAPOL: External notification - EAP fail=0
> 1253527140.795542: EAPOL: External notification - portControl=Auto
> 1253527140.795559: nl80211: Authenticate (ifindex=34)
> 1253527140.795572:   * bssid=00:13:19:80:da:30
> 1253527140.795587:   * freq=2412
> 1253527140.795598:   * SSID - hexdump_ascii(len=5):
>      4d 4e 57 50 41                                    MNWPA
> 1253527140.795630:   * IEs - hexdump(len=0): [NULL]
> 1253527140.795643:   * Auth Type 0
> 1253527140.795683: nl80211: Authentication request send successfully
> 1253527140.795707: RTM_NEWLINK: operstate=1 ifi_flags=0x11043 ([UP][RUNNING][LOWER_UP])
> 1253527140.795725: RTM_NEWLINK, IFLA_IFNAME: Interface 'eth1' added
> 1253527140.953161: nl80211: Event message available
> 1253527140.953200: nl80211: MLME event 37
> 1253527140.953216: SME: Authentication response: peer=00:13:19:80:da:30 auth_type=0 status_code=0
> 1253527140.953243: Trying to associate with 00:13:19:80:da:30 (SSID='MNWPA' freq=2412 MHz)
> 1253527140.953257: State: AUTHENTICATING -> ASSOCIATING
> 1253527140.953270: wpa_driver_nl80211_set_operstate: operstate 1->0 (DORMANT)
> 1253527140.953284: nl80211: Operstate: linkmode=-1, operstate=5
> 1253527140.953901: nl80211: Associate (ifindex=34)
> 1253527140.953919:   * bssid=00:13:19:80:da:30
> 1253527140.953934:   * freq=2412
> 1253527140.953945:   * SSID - hexdump_ascii(len=5):
>      4d 4e 57 50 41                                    MNWPA
> 1253527140.953977:   * IEs - hexdump(len=24): dd 16 00 50 f2 01 01 00 00 50 f2 02 01 00 00 50 f2 02 01 00 00 50 f2 02
> 1253527140.954064: nl80211: MLME command failed: ret=-114 (Operation already in progress)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 1253527140.954086: Association request to the driver failed
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 1253527140.954113: RTM_NEWLINK: operstate=0 ifi_flags=0x11003 ([UP][LOWER_UP])
> 1253527140.954131: RTM_NEWLINK, IFLA_IFNAME: Interface 'eth1' added
> 
> 
> The "Association request to the driver failed" will
> be shown even without "-d". Also note that the association
> seems to actually work, e.g. I can ping throught the
> connection.

Could this be related to the problem Maxim has been seeing? I'm not sure
how else this could happen since you seem to auth but then assoc doesn't
work, but I can't see how that could possibly happen.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* ath9k ar9220-ar9223 problem
From: Thomas Budicin @ 2009-10-10 17:40 UTC (permalink / raw)
  To: linux-wireless

Hi!

I'm fromItaly I have a problem with a mini pci card with two chip 
onboard ar9220 and ar9223.

When i try to load ath9k kernel 2.6.31 i get

ath: EEPROM regdomain: 0x164
ath: EEPROM indicates we should expect a direct regpair map
ath: invalid regulatory domain/country code 0x164
ath: Invalid EEPROM contents

Can you help me?

Rgds,
Thomas


^ permalink raw reply

* Re: [PATCH 1/3] iwmc3200top: Add Intel Wireless MultiCom 3200 top driver.
From: Tomas Winkler @ 2009-10-10 18:05 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: davem, linville, netdev, linux-wireless, linux-mmc, yi.zhu,
	inaky.perez-gonzalez, cindy.h.kao, guy.cohen, ron.rindjunsky
In-Reply-To: <1255172508.19127.22.camel@localhost.localdomain>

On Sat, Oct 10, 2009 at 1:01 PM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Tomas,
>
>> This patch adds Intel Wireless MultiCom 3200 top driver.
>> IWMC3200 is 4Wireless Com CHIP (GPS/BT/WiFi/WiMAX).
>> Top driver is responsible for device initialization and firmware download.
>> Firmware handled by top is responsible for top itself and
>> as well as bluetooth and GPS coms. (Wifi and WiMax provide their own
>> firmware)
>> In addition top driver is used to retrieve firmware logs
>> and supports other debugging features
>>
>> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
>> ---
>>  drivers/misc/Kconfig                   |    1 +
>>  drivers/misc/Makefile                  |    1 +
>>  drivers/misc/iwmc3200top/Kconfig       |   20 +
>>  drivers/misc/iwmc3200top/Makefile      |   29 ++
>>  drivers/misc/iwmc3200top/debugfs.c     |  145 +++++++
>>  drivers/misc/iwmc3200top/debugfs.h     |   61 +++
>>  drivers/misc/iwmc3200top/fw-download.c |  359 ++++++++++++++++
>>  drivers/misc/iwmc3200top/fw-msg.h      |  113 +++++
>>  drivers/misc/iwmc3200top/iwmc3200top.h |  202 +++++++++
>>  drivers/misc/iwmc3200top/log.c         |  339 +++++++++++++++
>>  drivers/misc/iwmc3200top/log.h         |  158 +++++++
>>  drivers/misc/iwmc3200top/main.c        |  702 ++++++++++++++++++++++++++++++++
>>  12 files changed, 2130 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/misc/iwmc3200top/Kconfig
>>  create mode 100644 drivers/misc/iwmc3200top/Makefile
>>  create mode 100644 drivers/misc/iwmc3200top/debugfs.c
>>  create mode 100644 drivers/misc/iwmc3200top/debugfs.h
>>  create mode 100644 drivers/misc/iwmc3200top/fw-download.c
>>  create mode 100644 drivers/misc/iwmc3200top/fw-msg.h
>>  create mode 100644 drivers/misc/iwmc3200top/iwmc3200top.h
>>  create mode 100644 drivers/misc/iwmc3200top/log.c
>>  create mode 100644 drivers/misc/iwmc3200top/log.h
>>  create mode 100644 drivers/misc/iwmc3200top/main.c
>>
>> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
>> index 68ab39d..6f85b43 100644
>> --- a/drivers/misc/Kconfig
>> +++ b/drivers/misc/Kconfig
>> @@ -236,5 +236,6 @@ config ISL29003
>>  source "drivers/misc/c2port/Kconfig"
>>  source "drivers/misc/eeprom/Kconfig"
>>  source "drivers/misc/cb710/Kconfig"
>> +source "drivers/misc/iwmc3200top/Kconfig"
>>
>>  endif # MISC_DEVICES
>> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
>> index 36f733c..97f5303 100644
>> --- a/drivers/misc/Makefile
>> +++ b/drivers/misc/Makefile
>> @@ -20,5 +20,6 @@ obj-$(CONFIG_SGI_GRU)               += sgi-gru/
>>  obj-$(CONFIG_HP_ILO)         += hpilo.o
>>  obj-$(CONFIG_ISL29003)               += isl29003.o
>>  obj-$(CONFIG_C2PORT)         += c2port/
>> +obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
>>  obj-y                                += eeprom/
>>  obj-y                                += cb710/
>> diff --git a/drivers/misc/iwmc3200top/Kconfig b/drivers/misc/iwmc3200top/Kconfig
>> new file mode 100644
>> index 0000000..9e4b88f
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/Kconfig
>> @@ -0,0 +1,20 @@
>> +config IWMC3200TOP
>> +        tristate "Intel Wireless MultiCom Top Driver"
>> +        depends on MMC && EXPERIMENTAL
>> +        select FW_LOADER
>> +     ---help---
>> +       Intel Wireless MultiCom 3200 Top driver is responsible for
>> +       for firmware load and enabled coms enumeration
>> +
>> +config IWMC3200TOP_DEBUG
>> +     bool "Enable full debug output of iwmc3200top Driver"
>> +     depends on IWMC3200TOP
>> +     ---help---
>> +       Enable full debug output of iwmc3200top Driver
>> +
>> +config IWMC3200TOP_DEBUGFS
>> +     bool "Enable Debugfs debugging interface for iwmc3200top"
>> +     depends on IWMC3200TOP
>> +     ---help---
>> +       Enable creation of debugfs files for iwmc3200top
>> +
>> diff --git a/drivers/misc/iwmc3200top/Makefile b/drivers/misc/iwmc3200top/Makefile
>> new file mode 100644
>> index 0000000..fbf53fb
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/Makefile
>> @@ -0,0 +1,29 @@
>> +# iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> +# drivers/misc/iwmc3200top/Makefile
>> +#
>> +# Copyright (C) 2009 Intel Corporation. All rights reserved.
>> +#
>> +# This program is free software; you can redistribute it and/or
>> +# modify it under the terms of the GNU General Public License version
>> +# 2 as published by the Free Software Foundation.
>> +#
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> +# GNU General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU General Public License
>> +# along with this program; if not, write to the Free Software
>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> +# 02110-1301, USA.
>> +#
>> +#
>> +# Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> +#  -
>> +#
>> +#
>> +
>> +obj-$(CONFIG_IWMC3200TOP)    += iwmc3200top.o
>> +iwmc3200top-objs     := main.o fw-download.o
>> +iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUG) += log.o
>> +iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUGFS) += debugfs.o
>> diff --git a/drivers/misc/iwmc3200top/debugfs.c b/drivers/misc/iwmc3200top/debugfs.c
>> new file mode 100644
>> index 0000000..a531f6c
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/debugfs.c
>> @@ -0,0 +1,145 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/debufs.c
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/string.h>
>> +#include <linux/ctype.h>
>> +#include <linux/mmc/sdio_func.h>
>> +#include <linux/mmc/sdio.h>
>> +
>> +#include "iwmc3200top.h"
>> +#include "log.h"
>> +#include "fw-msg.h"
>> +#include "debugfs.h"
>> +
>> +/*      Constants definition        */
>> +#define HEXADECIMAL_RADIX    16
>> +
>> +/*      Functions definition        */
>> +
>> +
>> +/*      Debugfs macros       */
>> +#define DEBUGFS_ADD_DIR(name, parent) do {                   \
>> +     dbgfs->dir_##name = debugfs_create_dir(#name, parent);  \
>> +     if (!(dbgfs->dir_##name))                               \
>> +             goto err;                                       \
>> +} while (0)
>> +
>> +#define DEBUGFS_ADD_FILE(name, parent) do {                          \
>> +     dbgfs->dbgfs_##parent##_files.file_##name =                     \
>> +     debugfs_create_file(#name, 0644, dbgfs->dir_##parent, priv,     \
>> +                             &iwmct_dbgfs_##name##_ops);               \
>> +     if (!(dbgfs->dbgfs_##parent##_files.file_##name))               \
>> +             goto err;                                               \
>> +} while (0)
>> +
>> +#define DEBUGFS_REMOVE(name)  do {   \
>> +     debugfs_remove(name);           \
>> +     name = NULL;                    \
>> +} while (0)
>> +
>> +#define DEBUGFS_READ_FUNC(name)                                              \
>> +ssize_t iwmct_dbgfs_##name##_read(struct file *file,                 \
>> +                               char __user *user_buf,                \
>> +                               size_t count, loff_t *ppos);
>> +
>> +#define DEBUGFS_WRITE_FUNC(name)                                     \
>> +ssize_t iwmct_dbgfs_##name##_write(struct file *file,                        \
>> +                                const char __user *user_buf,         \
>> +                                size_t count, loff_t *ppos);
>> +
>> +#define DEBUGFS_READ_FILE_OPS(name)                                  \
>> +     DEBUGFS_READ_FUNC(name)                                         \
>> +     static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
>> +             .read = iwmct_dbgfs_##name##_read,                      \
>> +             .open = iwmct_dbgfs_open_file_generic,                  \
>> +     };
>> +
>> +#define DEBUGFS_WRITE_FILE_OPS(name)                                 \
>> +     DEBUGFS_WRITE_FUNC(name)                                        \
>> +     static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
>> +             .write = iwmct_dbgfs_##name##_write,                    \
>> +             .open = iwmct_dbgfs_open_file_generic,                  \
>> +     };
>> +
>> +#define DEBUGFS_READ_WRITE_FILE_OPS(name)                            \
>> +     DEBUGFS_READ_FUNC(name)                                         \
>> +     DEBUGFS_WRITE_FUNC(name)                                        \
>> +     static const struct file_operations iwmct_dbgfs_##name##_ops = {\
>> +             .write = iwmct_dbgfs_##name##_write,                    \
>> +             .read = iwmct_dbgfs_##name##_read,                      \
>> +             .open = iwmct_dbgfs_open_file_generic,                  \
>> +     };
>> +
>> +
>> +/*      Debugfs file ops definitions        */
>> +
>> +/*      Debugfs registration functions        */
>> +
>> +/*
>> + * Create the debugfs files and directories
>> + *
>> + */
>
> so for me the whole debug infrastructure is way too much overhead for
> what this driver has to achieve. What is the benefit of having all these
> debugfs support. What is it trying to achieve?

There is some testing infrastracture built erround debugfs, it
exericeses the firmware. There is no use for
it outside our development so we ripped it off but removing also
debugfs will nightmare to maintain.
>
> Also all these macros really obfuscate the code for no real benefit. If
> you wanna keep debugfs support, then just use the functions directly.
> They are not that complicated that an extra abstraction layer is needed.
>
I believe the macros were  borrowed from wireless code.  They shalll
reduce codelines
but I have no strong feelings about them

Thanks for your comments I will address them in consequitve patch.

Thanks
Tomas

>> +void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
>> +{
>> +     struct iwmct_debugfs *dbgfs;
>> +
>> +     dbgfs = kzalloc(sizeof(struct iwmct_debugfs), GFP_KERNEL);
>> +     if (!dbgfs) {
>> +             LOG_ERROR(priv, DEBUGFS, "failed to allocate %zd bytes\n",
>> +                                     sizeof(struct iwmct_debugfs));
>> +             goto err;
>> +     }
>> +
>> +     priv->dbgfs = dbgfs;
>> +     dbgfs->name = name;
>> +     dbgfs->dir_drv = debugfs_create_dir(name, NULL);
>> +     if (!dbgfs->dir_drv) {
>> +             LOG_ERROR(priv, DEBUGFS, "failed to create debugfs dir\n");
>> +             goto err;
>> +     }
>> +
>> +
>> +err:
>> +     return;
>> +}
>
> goto err. Seriously. Just call return in the error case. And also there
> is a memory leak if the debugfs_create_dir fails.
>

>> +/**
>> + * Remove the debugfs files and directories
>> + *
>> + */
>> +void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
>> +{
>> +     if (!dbgfs)
>> +             return;
>> +
>> +
>> +     DEBUGFS_REMOVE(dbgfs->dir_drv);
>> +     kfree(dbgfs);
>> +
>> +     dbgfs = NULL;
>> +}
>> +
>> diff --git a/drivers/misc/iwmc3200top/debugfs.h b/drivers/misc/iwmc3200top/debugfs.h
>> new file mode 100644
>> index 0000000..24b1369
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/debugfs.h
>> @@ -0,0 +1,61 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/debufs.h
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#ifndef __DEBUGFS_H__
>> +#define __DEBUGFS_H__
>> +
>> +
>> +#ifdef CONFIG_IWMC3200TOP_DEBUGFS
>> +
>> +#include <linux/debugfs.h>
>> +
>> +struct iwmct_debugfs {
>> +     const char *name;
>> +     struct dentry *dir_drv;
>> +     struct dir_drv_files {
>> +     } dbgfs_drv_files;
>> +};
>> +
>> +void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name);
>> +void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs);
>> +
>> +#else /* CONFIG_IWMC3200TOP_DEBUGFS */
>> +
>> +/* struct iwmct_debugfs is empty if CONFIG_IWMC3200TOP_DEBUGFS is not defined */
>> +struct iwmct_debugfs {
>> +};
>
> If struct iwmct_debugfs is never referenced directly then a simple
> forward struct imwct_debugfs; declaration is good enough.
>
>> +
>> +static inline void
>> +iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
>> +{}
>> +
>> +static inline void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
>> +{}
>> +
>> +#endif /* CONFIG_IWMC3200TOP_DEBUGFS */
>> +
>> +#endif /* __DEBUGFS_H__ */
>> +
>> diff --git a/drivers/misc/iwmc3200top/fw-download.c b/drivers/misc/iwmc3200top/fw-download.c
>> new file mode 100644
>> index 0000000..33cb693
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/fw-download.c
>> @@ -0,0 +1,359 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/fw-download.c
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/mmc/sdio_func.h>
>> +#include <asm/unaligned.h>
>> +
>> +#include "iwmc3200top.h"
>> +#include "log.h"
>> +#include "fw-msg.h"
>> +
>> +#define CHECKSUM_BYTES_NUM sizeof(u32)
>> +
>> +/**
>> +  init parser struct with file
>> + */
>> +static int iwmct_fw_parser_init(struct iwmct_priv *priv, const u8 *file,
>> +                           size_t file_size, size_t block_size)
>> +{
>> +     struct iwmct_parser *parser = &priv->parser;
>> +     struct iwmct_fw_hdr *fw_hdr = &parser->versions;
>> +
>> +     LOG_INFOEX(priv, INIT, "-->\n");
>> +
>> +     LOG_INFO(priv, FW_DOWNLOAD, "file_size=%zd\n", file_size);
>
> This logging is overkill. Can we just hide this via pr_debug and then
> use just simply dynamic_printk support.
>
>> +
>> +     parser->file = file;
>> +     parser->file_size = file_size;
>> +     parser->cur_pos = 0;
>> +     parser->buf = NULL;
>> +
>> +     parser->buf = kzalloc(block_size, GFP_KERNEL);
>> +     if (!parser->buf) {
>> +             LOG_ERROR(priv, FW_DOWNLOAD, "kzalloc error\n");
>> +             return -ENOMEM;
>> +     }
>> +     parser->buf_size = block_size;
>> +
>> +     /* extract fw versions */
>> +     memcpy(fw_hdr, parser->file, sizeof(struct iwmct_fw_hdr));
>> +     LOG_INFO(priv, FW_DOWNLOAD, "fw versions are:\n"
>> +             "top %u.%u.%u gps %u.%u.%u bt %u.%u.%u tic %s\n",
>> +             fw_hdr->top_major, fw_hdr->top_minor, fw_hdr->top_revision,
>> +             fw_hdr->gps_major, fw_hdr->gps_minor, fw_hdr->gps_revision,
>> +             fw_hdr->bt_major, fw_hdr->bt_minor, fw_hdr->bt_revision,
>> +             fw_hdr->tic_name);
>> +
>> +     parser->cur_pos += sizeof(struct iwmct_fw_hdr);
>> +
>> +     LOG_INFOEX(priv, INIT, "<--\n");
>> +     return 0;
>> +}
>> +
>> +static bool iwmct_checksum(struct iwmct_priv *priv)
>> +{
>> +     struct iwmct_parser *parser = &priv->parser;
>> +     __le32 *file = (__le32 *)parser->file;
>> +     int i, pad, steps;
>> +     u32 accum = 0;
>> +     u32 checksum;
>> +     u32 mask = 0xffffffff;
>> +
>> +     pad = (parser->file_size - CHECKSUM_BYTES_NUM) % 4;
>> +     steps =  (parser->file_size - CHECKSUM_BYTES_NUM) / 4;
>> +
>> +     LOG_INFO(priv, FW_DOWNLOAD, "pad=%d steps=%d\n", pad, steps);
>> +
>> +     for (i = 0; i < steps; i++)
>> +             accum += le32_to_cpu(file[i]);
>> +
>> +     if (pad) {
>> +             mask <<= 8 * (4 - pad);
>> +             accum += le32_to_cpu(file[steps]) & mask;
>> +     }
>> +
>> +     checksum = get_unaligned_le32((__le32 *)(parser->file +
>> +                     parser->file_size - CHECKSUM_BYTES_NUM));
>
> The access to file and parser->file. One with unaligned access and the
> other with, looks wrong. And it looks way to complicated.
>
> Can we just not have a proper __le32 type of parser->file to begin with.
>
>> +
>> +     LOG_INFO(priv, FW_DOWNLOAD,
>> +             "compare checksum accum=0x%x to checksum=0x%x\n",
>> +             accum, checksum);
>> +
>> +     return checksum == accum;
>> +}
>> +
>> +static int iwmct_parse_next_section(struct iwmct_priv *priv, const u8 **p_sec,
>> +                               size_t *sec_size, __le32 *sec_addr)
>> +{
>> +     struct iwmct_parser *parser = &priv->parser;
>> +     struct iwmct_dbg *dbg = &priv->dbg;
>> +     struct iwmct_fw_sec_hdr *sec_hdr;
>> +
>> +     LOG_INFOEX(priv, INIT, "-->\n");
>> +
>> +     while (parser->cur_pos + sizeof(struct iwmct_fw_sec_hdr)
>> +             <= parser->file_size) {
>> +
>> +             sec_hdr = (struct iwmct_fw_sec_hdr *)
>> +                             (parser->file + parser->cur_pos);
>> +             parser->cur_pos += sizeof(struct iwmct_fw_sec_hdr);
>> +
>> +             LOG_INFO(priv, FW_DOWNLOAD,
>> +                     "sec hdr: type=%s addr=0x%x size=%d\n",
>> +                     sec_hdr->type, sec_hdr->target_addr,
>> +                     sec_hdr->data_size);
>> +
>> +             if (strcmp(sec_hdr->type, "ENT") == 0)
>> +                     parser->entry_point = le32_to_cpu(sec_hdr->target_addr);
>> +             else if (strcmp(sec_hdr->type, "LBL") == 0)
>> +                     strcpy(dbg->label_fw, parser->file + parser->cur_pos);
>> +             else if (((strcmp(sec_hdr->type, "TOP") == 0) &&
>> +                       (priv->barker & BARKER_DNLOAD_TOP_MSK)) ||
>> +                      ((strcmp(sec_hdr->type, "GPS") == 0) &&
>> +                       (priv->barker & BARKER_DNLOAD_GPS_MSK)) ||
>> +                      ((strcmp(sec_hdr->type, "BTH") == 0) &&
>> +                       (priv->barker & BARKER_DNLOAD_BT_MSK))) {
>> +                     *sec_addr = sec_hdr->target_addr;
>> +                     *sec_size = le32_to_cpu(sec_hdr->data_size);
>> +                     *p_sec = parser->file + parser->cur_pos;
>> +                     parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
>> +                     return 1;
>
> This if statement is unreadable. This indentation gives me a headache.
>
> Also this function better return bool and not int.
>
>> +             } else if (strcmp(sec_hdr->type, "LOG") != 0)
>> +                     LOG_WARNING(priv, FW_DOWNLOAD,
>> +                                 "skipping section type %s\n",
>> +                                 sec_hdr->type);
>> +
>> +             parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
>> +             LOG_INFO(priv, FW_DOWNLOAD,
>> +                     "finished with section cur_pos=%zd\n", parser->cur_pos);
>> +     }
>> +
>> +     LOG_INFOEX(priv, INIT, "<--\n");
>> +     return 0;
>> +}
>> +
>> +static int iwmct_download_section(struct iwmct_priv *priv, const u8 *p_sec,
>> +                             size_t sec_size, __le32 addr)
>> +{
>> +     struct iwmct_parser *parser = &priv->parser;
>> +     struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
>> +     const u8 *cur_block = p_sec;
>> +     size_t sent = 0;
>> +     int cnt = 0;
>> +     int ret = 0;
>> +     u32 cmd = 0;
>> +
>> +     LOG_INFOEX(priv, INIT, "-->\n");
>> +     LOG_INFO(priv, FW_DOWNLOAD, "Download address 0x%x size 0x%zx\n",
>> +                             addr, sec_size);
>> +
>> +     while (sent < sec_size) {
>> +             int i;
>> +             u32 chksm = 0;
>> +             u32 reset = atomic_read(&priv->reset);
>> +             /* actual FW data */
>> +             u32 data_size = min(parser->buf_size - sizeof(*hdr),
>> +                                 sec_size - sent);
>> +             /* Pad to block size */
>> +             u32 trans_size = (data_size + sizeof(*hdr) +
>> +                               IWMC_SDIO_BLK_SIZE - 1) &
>> +                               ~(IWMC_SDIO_BLK_SIZE - 1);
>> +             ++cnt;
>> +
>> +             /* in case of reset, interrupt FW DOWNLAOD */
>> +             if (reset) {
>> +                     LOG_INFO(priv, FW_DOWNLOAD,
>> +                              "Reset detected. Abort FW download!!!");
>> +                     ret = -ECANCELED;
>> +                     goto exit;
>> +             }
>> +
>> +             memset(parser->buf, 0, parser->buf_size);
>> +             cmd |= IWMC_OPCODE_WRITE << CMD_HDR_OPCODE_POS;
>> +             cmd |= IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
>> +             cmd |= (priv->dbg.direct ? 1 : 0) << CMD_HDR_DIRECT_ACCESS_POS;
>> +             cmd |= (priv->dbg.checksum ? 1 : 0) << CMD_HDR_USE_CHECKSUM_POS;
>> +             hdr->data_size = cpu_to_le32(data_size);
>> +             hdr->target_addr = addr;
>> +
>> +             /* checksum is allowed for sizes divisible by 4 */
>> +             if (data_size & 0x3)
>> +                     cmd &= ~CMD_HDR_USE_CHECKSUM_MSK;
>> +
>> +             memcpy(hdr->data, cur_block, data_size);
>> +
>> +
>> +             if (cmd & CMD_HDR_USE_CHECKSUM_MSK) {
>> +
>> +                     chksm = data_size + le32_to_cpu(addr) + cmd;
>> +                     for (i = 0; i < data_size >> 2; i++)
>> +                             chksm += ((u32 *)cur_block)[i];
>> +
>> +                     hdr->block_chksm = cpu_to_le32(chksm);
>> +                     LOG_INFO(priv, FW_DOWNLOAD, "Checksum = 0x%X\n",
>> +                              hdr->block_chksm);
>> +             }
>> +
>> +             LOG_INFO(priv, FW_DOWNLOAD, "trans#%d, len=%d, sent=%zd, "
>> +                             "sec_size=%zd, startAddress 0x%X\n",
>> +                             cnt, trans_size, sent, sec_size, addr);
>> +
>> +             if (priv->dbg.dump)
>> +                     LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, trans_size);
>> +
>> +
>> +             hdr->cmd = cpu_to_le32(cmd);
>> +             /* send it down */
>> +             /* TODO: add more proper sending and error checking */
>> +             ret = iwmct_tx(priv, 0, parser->buf, trans_size);
>> +             if (ret != 0) {
>> +                     LOG_INFO(priv, FW_DOWNLOAD,
>> +                             "iwmct_tx returned %d\n", ret);
>> +                     goto exit;
>> +             }
>> +
>> +             addr = cpu_to_le32(le32_to_cpu(addr) + data_size);
>> +             sent += data_size;
>> +             cur_block = p_sec + sent;
>> +
>> +             if (priv->dbg.blocks && (cnt + 1) >= priv->dbg.blocks) {
>> +                     LOG_INFO(priv, FW_DOWNLOAD,
>> +                             "Block number limit is reached [%d]\n",
>> +                             priv->dbg.blocks);
>> +                     break;
>> +             }
>> +     }
>> +
>> +     if (sent < sec_size)
>> +             ret = -EINVAL;
>> +exit:
>> +     LOG_INFOEX(priv, INIT, "<--\n");
>> +     return ret;
>> +}
>> +
>> +static int iwmct_kick_fw(struct iwmct_priv *priv, bool jump)
>> +{
>> +     struct iwmct_parser *parser = &priv->parser;
>> +     struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
>> +     int ret;
>> +     u32 cmd;
>> +
>> +     LOG_INFOEX(priv, INIT, "-->\n");
>> +
>> +     memset(parser->buf, 0, parser->buf_size);
>> +     cmd = IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
>> +     if (jump) {
>> +             cmd |= IWMC_OPCODE_JUMP << CMD_HDR_OPCODE_POS;
>> +             hdr->target_addr = cpu_to_le32(parser->entry_point);
>> +             LOG_INFO(priv, FW_DOWNLOAD, "jump address 0x%x\n",
>> +                             parser->entry_point);
>> +     } else {
>> +             cmd |= IWMC_OPCODE_LAST_COMMAND << CMD_HDR_OPCODE_POS;
>> +             LOG_INFO(priv, FW_DOWNLOAD, "last command\n");
>> +     }
>> +
>> +     hdr->cmd = cpu_to_le32(cmd);
>> +
>> +     LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, sizeof(*hdr));
>> +     /* send it down */
>> +     /* TODO: add more proper sending and error checking */
>> +     ret = iwmct_tx(priv, 0, parser->buf, IWMC_SDIO_BLK_SIZE);
>> +     if (ret)
>> +             LOG_INFO(priv, FW_DOWNLOAD, "iwmct_tx returned %d", ret);
>> +
>> +     LOG_INFOEX(priv, INIT, "<--\n");
>> +     return 0;
>> +}
>> +
>> +int iwmct_fw_load(struct iwmct_priv *priv)
>> +{
>> +     const struct firmware *raw = NULL;
>> +     __le32 addr;
>> +     size_t len;
>> +     const u8 *pdata;
>> +     const u8 *name = "iwmc3200top.1.fw";
>> +     int ret = 0;
>> +
>> +     /* clear parser struct */
>> +     memset(&priv->parser, 0, sizeof(struct iwmct_parser));
>> +     if (!name) {
>> +             ret = -EINVAL;
>> +             goto exit;
>> +     }
>> +
>> +     /* get the firmware */
>> +     ret = request_firmware(&raw, name, &priv->func->dev);
>> +     if (ret < 0) {
>> +             LOG_ERROR(priv, FW_DOWNLOAD, "%s request_firmware failed %d\n",
>> +                       name, ret);
>> +             goto exit;
>> +     }
>> +
>> +     if (raw->size < sizeof(struct iwmct_fw_sec_hdr)) {
>> +             LOG_ERROR(priv, FW_DOWNLOAD, "%s smaller then (%zd) (%zd)\n",
>> +                       name, sizeof(struct iwmct_fw_sec_hdr), raw->size);
>> +             goto exit;
>> +     }
>> +
>> +     LOG_INFO(priv, FW_DOWNLOAD, "Read firmware '%s'\n", name);
>> +
>> +     ret = iwmct_fw_parser_init(priv, raw->data, raw->size, priv->trans_len);
>> +     if (ret < 0) {
>> +             LOG_ERROR(priv, FW_DOWNLOAD,
>> +                       "iwmct_parser_init failed: Reason %d\n", ret);
>> +             goto exit;
>> +     }
>> +
>> +     /* checksum  */
>> +     if (!iwmct_checksum(priv)) {
>> +             LOG_ERROR(priv, FW_DOWNLOAD, "checksum error\n");
>> +             ret = -EINVAL;
>> +             goto exit;
>> +     }
>> +
>> +     /* download firmware to device */
>> +     while (iwmct_parse_next_section(priv, &pdata, &len, &addr)) {
>> +             if (iwmct_download_section(priv, pdata, len, addr)) {
>> +                     LOG_ERROR(priv, FW_DOWNLOAD,
>> +                               "%s download section failed\n", name);
>> +                     ret = -EIO;
>> +                     goto exit;
>> +             }
>> +     }
>> +
>> +     iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));
>> +
>> +exit:
>> +     kfree(priv->parser.buf);
>> +
>> +     if (raw)
>> +             release_firmware(raw);
>> +
>> +     raw = NULL;
>> +
>> +     return ret;
>> +}
>> diff --git a/drivers/misc/iwmc3200top/fw-msg.h b/drivers/misc/iwmc3200top/fw-msg.h
>> new file mode 100644
>> index 0000000..9e26b75
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/fw-msg.h
>> @@ -0,0 +1,113 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/fw-msg.h
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#ifndef __FWMSG_H__
>> +#define __FWMSG_H__
>> +
>> +#define COMM_TYPE_D2H                0xFF
>> +#define COMM_TYPE_H2D                0xEE
>> +
>> +#define COMM_CATEGORY_OPERATIONAL            0x00
>> +#define COMM_CATEGORY_DEBUG                  0x01
>> +#define COMM_CATEGORY_TESTABILITY            0x02
>> +#define COMM_CATEGORY_DIAGNOSTICS            0x03
>> +
>> +#define OP_DBG_ZSTR_MSG                      cpu_to_le16(0x1A)
>> +
>> +#define FW_LOG_SRC_MAX                       32
>> +#define FW_LOG_SRC_ALL                       255
>> +
>> +#define FW_STRING_TABLE_ADDR         cpu_to_le32(0x0C000000)
>> +
>> +#define CMD_DBG_LOG_LEVEL            cpu_to_le16(0x0001)
>> +#define CMD_TST_DEV_RESET            cpu_to_le16(0x0060)
>> +#define CMD_TST_FUNC_RESET           cpu_to_le16(0x0062)
>> +#define CMD_TST_IFACE_RESET          cpu_to_le16(0x0064)
>> +#define CMD_TST_CPU_UTILIZATION              cpu_to_le16(0x0065)
>> +#define CMD_TST_TOP_DEEP_SLEEP               cpu_to_le16(0x0080)
>> +#define CMD_TST_WAKEUP                       cpu_to_le16(0x0081)
>> +#define CMD_TST_FUNC_WAKEUP          cpu_to_le16(0x0082)
>> +#define CMD_TST_FUNC_DEEP_SLEEP_REQUEST      cpu_to_le16(0x0083)
>> +#define CMD_TST_GET_MEM_DUMP         cpu_to_le16(0x0096)
>> +
>> +#define OP_OPR_ALIVE                 cpu_to_le16(0x0010)
>> +#define OP_OPR_CMD_ACK                       cpu_to_le16(0x001F)
>> +#define OP_OPR_CMD_NACK                      cpu_to_le16(0x0020)
>> +#define OP_TST_MEM_DUMP                      cpu_to_le16(0x0043)
>> +
>> +#define CMD_FLAG_PADDING_256         0x80
>> +
>> +#define FW_HCMD_BLOCK_SIZE           256
>> +
>> +struct msg_hdr {
>> +     u8 type;
>> +     u8 category;
>> +     __le16 opcode;
>> +     u8 seqnum;
>> +     u8 flags;
>> +     __le16 length;
>> +} __attribute__((__packed__));
>> +
>> +struct log_hdr {
>> +     __le32 timestamp;
>> +     u8 severity;
>> +     u8 logsource;
>> +     __le16 reserved;
>> +} __attribute__((__packed__));
>> +
>> +struct mdump_hdr {
>> +     u8 dmpid;
>> +     u8 frag;
>> +     __le16 size;
>> +     __le32 addr;
>> +} __attribute__((__packed__));
>> +
>> +struct top_msg {
>> +     struct msg_hdr hdr;
>> +     union {
>> +             /* D2H messages */
>> +             struct {
>> +                     struct log_hdr log_hdr;
>> +                     u8 data[1];
>> +             } __attribute__((__packed__)) log;
>> +
>> +             struct {
>> +                     struct log_hdr log_hdr;
>> +                     struct mdump_hdr md_hdr;
>> +                     u8 data[1];
>> +             } __attribute__((__packed__)) mdump;
>> +
>> +             /* H2D messages */
>> +             struct {
>> +                     u8 logsource;
>> +                     u8 sevmask;
>> +             } __attribute__((__packed__)) logdefs[FW_LOG_SRC_MAX];
>> +             struct mdump_hdr mdump_req;
>> +     } u;
>> +} __attribute__((__packed__));
>> +
>> +
>> +#endif /* __FWMSG_H__ */
>> diff --git a/drivers/misc/iwmc3200top/iwmc3200top.h b/drivers/misc/iwmc3200top/iwmc3200top.h
>> new file mode 100644
>> index 0000000..59e4b7a
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/iwmc3200top.h
>> @@ -0,0 +1,202 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/iwmc3200top.h
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#ifndef __IWMC3200TOP_H__
>> +#define __IWMC3200TOP_H__
>> +
>> +#define DRV_NAME "iwmc3200top"
>> +
>> +#define IWMC_SDIO_BLK_SIZE                   256
>> +#define IWMC_DEFAULT_TR_BLK                  64
>> +#define IWMC_SDIO_DATA_ADDR                  0x0
>> +#define IWMC_SDIO_INTR_ENABLE_ADDR           0x14
>> +#define IWMC_SDIO_INTR_STATUS_ADDR           0x13
>> +#define IWMC_SDIO_INTR_CLEAR_ADDR            0x13
>> +#define IWMC_SDIO_INTR_GET_SIZE_ADDR         0x2C
>> +
>> +#define COMM_HUB_HEADER_LENGTH 16
>> +#define LOGGER_HEADER_LENGTH   10
>> +
>> +
>> +#define BARKER_DNLOAD_BT_POS         0
>> +#define BARKER_DNLOAD_BT_MSK         BIT(BARKER_DNLOAD_BT_POS)
>> +#define BARKER_DNLOAD_GPS_POS                1
>> +#define BARKER_DNLOAD_GPS_MSK                BIT(BARKER_DNLOAD_GPS_POS)
>> +#define BARKER_DNLOAD_TOP_POS                2
>> +#define BARKER_DNLOAD_TOP_MSK                BIT(BARKER_DNLOAD_TOP_POS)
>> +#define BARKER_DNLOAD_RESERVED1_POS  3
>> +#define BARKER_DNLOAD_RESERVED1_MSK  BIT(BARKER_DNLOAD_RESERVED1_POS)
>> +#define BARKER_DNLOAD_JUMP_POS               4
>> +#define BARKER_DNLOAD_JUMP_MSK               BIT(BARKER_DNLOAD_JUMP_POS)
>> +#define BARKER_DNLOAD_SYNC_POS               5
>> +#define BARKER_DNLOAD_SYNC_MSK               BIT(BARKER_DNLOAD_SYNC_POS)
>> +#define BARKER_DNLOAD_RESERVED2_POS  6
>> +#define BARKER_DNLOAD_RESERVED2_MSK  (0x3 << BARKER_DNLOAD_RESERVED2_POS)
>> +#define BARKER_DNLOAD_BARKER_POS     8
>> +#define BARKER_DNLOAD_BARKER_MSK     (0xffffff << BARKER_DNLOAD_BARKER_POS)
>> +
>> +#define IWMC_BARKER_REBOOT   (0xdeadbe << BARKER_DNLOAD_BARKER_POS)
>> +/* whole field barker */
>> +#define IWMC_BARKER_ACK      0xfeedbabe
>> +
>> +#define IWMC_CMD_SIGNATURE   0xcbbc
>> +
>> +#define CMD_HDR_OPCODE_POS           0
>> +#define CMD_HDR_OPCODE_MSK_MSK               (0xf << CMD_HDR_OPCODE_MSK_POS)
>> +#define CMD_HDR_RESPONSE_CODE_POS    4
>> +#define CMD_HDR_RESPONSE_CODE_MSK    (0xf << CMD_HDR_RESPONSE_CODE_POS)
>> +#define CMD_HDR_USE_CHECKSUM_POS     8
>> +#define CMD_HDR_USE_CHECKSUM_MSK     BIT(CMD_HDR_USE_CHECKSUM_POS)
>> +#define CMD_HDR_RESPONSE_REQUIRED_POS        9
>> +#define CMD_HDR_RESPONSE_REQUIRED_MSK        BIT(CMD_HDR_RESPONSE_REQUIRED_POS)
>> +#define CMD_HDR_DIRECT_ACCESS_POS    10
>> +#define CMD_HDR_DIRECT_ACCESS_MSK    BIT(CMD_HDR_DIRECT_ACCESS_POS)
>> +#define CMD_HDR_RESERVED_POS         11
>> +#define CMD_HDR_RESERVED_MSK         BIT(0x1f << CMD_HDR_RESERVED_POS)
>> +#define CMD_HDR_SIGNATURE_POS                16
>> +#define CMD_HDR_SIGNATURE_MSK                BIT(0xffff << CMD_HDR_SIGNATURE_POS)
>> +
>> +enum {
>> +     IWMC_OPCODE_PING = 0,
>> +     IWMC_OPCODE_READ = 1,
>> +     IWMC_OPCODE_WRITE = 2,
>> +     IWMC_OPCODE_JUMP = 3,
>> +     IWMC_OPCODE_REBOOT = 4,
>> +     IWMC_OPCODE_PERSISTENT_WRITE = 5,
>> +     IWMC_OPCODE_PERSISTENT_READ = 6,
>> +     IWMC_OPCODE_READ_MODIFY_WRITE = 7,
>> +     IWMC_OPCODE_LAST_COMMAND = 15
>> +};
>> +
>> +struct iwmct_fw_load_hdr {
>> +     __le32 cmd;
>> +     __le32 target_addr;
>> +     __le32 data_size;
>> +     __le32 block_chksm;
>> +     u8 data[0];
>> +};
>> +
>> +/**
>> + * struct iwmct_fw_hdr
>> + * holds all sw components versions
>> + */
>> +struct iwmct_fw_hdr {
>> +     u8 top_major;
>> +     u8 top_minor;
>> +     u8 top_revision;
>> +     u8 gps_major;
>> +     u8 gps_minor;
>> +     u8 gps_revision;
>> +     u8 bt_major;
>> +     u8 bt_minor;
>> +     u8 bt_revision;
>> +     u8 tic_name[31];
>> +};
>> +
>> +/**
>> + * struct iwmct_fw_sec_hdr
>> + * @type: function type
>> + * @data_size: section's data size
>> + * @target_addr: download address
>> + */
>> +struct iwmct_fw_sec_hdr {
>> +     u8 type[4];
>> +     __le32 data_size;
>> +     __le32 target_addr;
>> +};
>> +
>> +/**
>> + * struct iwmct_parser
>> + * @file: fw image
>> + * @file_size: fw size
>> + * @cur_pos: position in file
>> + * @buf: temp buf for download
>> + * @buf_size: size of buf
>> + * @entry_point: address to jump in fw kick-off
>> + */
>> +struct iwmct_parser {
>> +     const u8 *file;
>> +     size_t file_size;
>> +     size_t cur_pos;
>> +     u8 *buf;
>> +     size_t buf_size;
>> +     u32 entry_point;
>> +     struct iwmct_fw_hdr versions;
>> +};
>> +
>> +
>> +struct iwmct_work_struct {
>> +     struct list_head list;
>> +     ssize_t iosize;
>> +};
>> +
>> +struct iwmct_dbg {
>> +     int blocks;
>> +     bool dump;
>> +     bool jump;
>> +     bool direct;
>> +     bool checksum;
>> +     bool fw_download;
>> +     int block_size;
>> +     int download_trans_blks;
>> +
>> +     char label_fw[256];
>> +};
>> +
>> +struct iwmct_priv {
>> +     struct sdio_func *func;
>> +     struct iwmct_debugfs *dbgfs;
>> +     struct iwmct_parser parser;
>> +     atomic_t reset;
>> +     atomic_t dev_sync;
>> +     u32 trans_len;
>> +     u32 barker;
>> +     struct iwmct_dbg dbg;
>> +
>> +     /* drivers work queue */
>> +     struct workqueue_struct *wq;
>> +     struct workqueue_struct *bus_rescan_wq;
>> +     struct work_struct bus_rescan_worker;
>> +     struct work_struct isr_worker;
>> +
>> +     /* drivers wait queue */
>> +     wait_queue_head_t wait_q;
>> +
>> +     /* rx request list */
>> +     struct list_head read_req_list;
>> +};
>> +
>> +extern int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
>> +             void *src, int count);
>> +
>> +extern int iwmct_fw_load(struct iwmct_priv *priv);
>> +
>> +extern void iwmct_dbg_init_params(struct iwmct_priv *drv);
>> +extern void iwmct_dbg_init_drv_attrs(struct device_driver *drv);
>> +extern void iwmct_dbg_remove_drv_attrs(struct device_driver *drv);
>> +extern int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len);
>> +
>> +#endif  /*  __IWMC3200TOP_H__  */
>> diff --git a/drivers/misc/iwmc3200top/log.c b/drivers/misc/iwmc3200top/log.c
>> new file mode 100644
>> index 0000000..96b5e4a
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/log.c
>> @@ -0,0 +1,339 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/log.c
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/mmc/sdio_func.h>
>> +#include <linux/ctype.h>
>> +#include "fw-msg.h"
>> +#include "iwmc3200top.h"
>> +#include "log.h"
>> +
>> +/* Maximal hexadecimal string size of the FW memdump message */
>> +#define LOG_MSG_SIZE_MAX             12400
>> +
>> +/* iwmct_logdefs is a global used by log macros */
>> +u8 iwmct_logdefs[LOG_SRC_MAX];
>> +static u8 iwmct_fw_logdefs[FW_LOG_SRC_MAX];
>> +
>> +
>> +static int _log_set_log_filter(u8 *logdefs, int size, u8 src, u8 logmask)
>> +{
>> +     int i;
>> +
>> +     if (src < size)
>> +             logdefs[src] = logmask;
>> +     else if (src == LOG_SRC_ALL)
>> +             for (i = 0; i < size; i++)
>> +                     logdefs[i] = logmask;
>> +     else
>> +             return -1;
>> +
>> +     return 0;
>> +}
>> +
>> +
>> +int iwmct_log_set_filter(u8 src, u8 logmask)
>> +{
>> +     return _log_set_log_filter(iwmct_logdefs, LOG_SRC_MAX, src, logmask);
>> +}
>> +
>> +
>> +int iwmct_log_set_fw_filter(u8 src, u8 logmask)
>> +{
>> +     return _log_set_log_filter(iwmct_fw_logdefs,
>> +                                FW_LOG_SRC_MAX, src, logmask);
>> +}
>> +
>> +
>> +static int log_msg_format_hex(char *str, int slen, u8 *ibuf,
>> +                           int ilen, char *pref)
>> +{
>> +     int pos = 0;
>> +     int i;
>> +     int len;
>> +
>> +     for (pos = 0, i = 0; pos < slen - 2 && pref[i] != '\0'; i++, pos++)
>> +             str[pos] = pref[i];
>> +
>> +     for (i = 0; pos < slen - 2 && i < ilen; pos += len, i++)
>> +             len = snprintf(&str[pos], slen - pos - 1, " %2.2X", ibuf[i]);
>> +
>> +     if (i < ilen)
>> +             return -1;
>> +
>> +     return 0;
>> +}
>> +
>> +/*   NOTE: This function is not thread safe.
>> +     Currently it's called only from sdio rx worker - no race there
>> +*/
>> +void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len)
>> +{
>> +     struct top_msg *msg;
>> +     static char logbuf[LOG_MSG_SIZE_MAX];
>> +
>> +     msg = (struct top_msg *)buf;
>> +
>> +     if (len < sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr)) {
>> +             LOG_ERROR(priv, FW_MSG, "Log message from TOP "
>> +                       "is too short %d (expected %zd)\n",
>> +                       len, sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr));
>> +             return;
>> +     }
>> +
>> +     if (!(iwmct_fw_logdefs[msg->u.log.log_hdr.logsource] &
>> +             BIT(msg->u.log.log_hdr.severity)) ||
>> +         !(iwmct_logdefs[LOG_SRC_FW_MSG] & BIT(msg->u.log.log_hdr.severity)))
>> +             return;
>> +
>> +     switch (msg->hdr.category) {
>> +     case COMM_CATEGORY_TESTABILITY:
>> +             if (!(iwmct_logdefs[LOG_SRC_TST] &
>> +                   BIT(msg->u.log.log_hdr.severity)))
>> +                     return;
>> +             if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
>> +                                    le16_to_cpu(msg->hdr.length) +
>> +                                    sizeof(msg->hdr), "<TST>"))
>> +                     LOG_WARNING(priv, TST,
>> +                               "TOP TST message is too long, truncating...");
>> +             LOG_WARNING(priv, TST, "%s\n", logbuf);
>> +             break;
>> +     case COMM_CATEGORY_DEBUG:
>> +             if (msg->hdr.opcode == OP_DBG_ZSTR_MSG)
>> +                     LOG_INFO(priv, FW_MSG, "%s %s", "<DBG>",
>> +                                    ((u8 *)msg) + sizeof(msg->hdr)
>> +                                     + sizeof(msg->u.log.log_hdr));
>> +             else {
>> +                     if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
>> +                                     le16_to_cpu(msg->hdr.length)
>> +                                             + sizeof(msg->hdr),
>> +                                     "<DBG>"))
>> +                             LOG_WARNING(priv, FW_MSG,
>> +                                     "TOP DBG message is too long,"
>> +                                     "truncating...");
>> +                     LOG_WARNING(priv, FW_MSG, "%s\n", logbuf);
>> +             }
>> +             break;
>> +     default:
>> +             break;
>> +     }
>> +}
>> +
>> +static int _log_get_filter_str(u8 *logdefs, int logdefsz, char *buf, int size)
>> +{
>> +     int i, pos, len;
>> +     for (i = 0, pos = 0; (pos < size-1) && (i < logdefsz); i++) {
>> +             len = snprintf(&buf[pos], size - pos - 1, "0x%02X%02X,",
>> +                             i, logdefs[i]);
>> +             pos += len;
>> +     }
>> +     buf[pos-1] = '\n';
>> +     buf[pos] = '\0';
>> +
>> +     if (i < logdefsz)
>> +             return -1;
>> +     return 0;
>> +}
>> +
>> +int log_get_filter_str(char *buf, int size)
>> +{
>> +     return _log_get_filter_str(iwmct_logdefs, LOG_SRC_MAX, buf, size);
>> +}
>> +
>> +int log_get_fw_filter_str(char *buf, int size)
>> +{
>> +     return _log_get_filter_str(iwmct_fw_logdefs, FW_LOG_SRC_MAX, buf, size);
>> +}
>> +
>> +#define HEXADECIMAL_RADIX    16
>> +#define LOG_SRC_FORMAT               7 /* log level is in format of "0xXXXX," */
>> +
>> +ssize_t show_iwmct_log_level(struct device *d,
>> +                             struct device_attribute *attr, char *buf)
>> +{
>> +     struct iwmct_priv *priv = d->driver_data;
>> +     char *str_buf;
>> +     int buf_size;
>> +     ssize_t ret = -EAGAIN;
>> +
>> +     buf_size = (LOG_SRC_FORMAT * LOG_SRC_MAX) + 1;
>> +     str_buf = kzalloc(buf_size, GFP_KERNEL);
>> +     if (!str_buf) {
>> +             LOG_ERROR(priv, DEBUGFS,
>> +                     "failed to allocate %d bytes\n", buf_size);
>> +             goto exit;
>> +     }
>> +
>> +     if (log_get_filter_str(str_buf, buf_size) < 0)
>> +             goto exit;
>> +
>> +     ret = sprintf(buf, "%s", str_buf);
>> +
>> +exit:
>> +     kfree(str_buf);
>> +     return ret;
>> +}
>> +
>> +ssize_t store_iwmct_log_level(struct device *d,
>> +                     struct device_attribute *attr,
>> +                     const char *buf, size_t count)
>> +{
>> +     struct iwmct_priv *priv = d->driver_data;
>> +     char *token, *str_buf = NULL;
>> +     long val;
>> +     u8 src, mask;
>> +
>> +     if (!count)
>> +             goto err;
>> +
>> +     str_buf = kzalloc(count, GFP_KERNEL);
>> +     if (!str_buf) {
>> +             LOG_ERROR(priv, DEBUGFS,
>> +                     "failed to allocate %zd bytes\n", count);
>> +             goto err;
>> +     }
>> +
>> +     memcpy(str_buf, buf, count);
>> +
>> +     while ((token = strsep(&str_buf, ",")) != NULL) {
>> +             while (isspace(*token))
>> +                     ++token;
>> +             if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
>> +                     LOG_ERROR(priv, DEBUGFS,
>> +                               "failed to convert string to long %s\n",
>> +                               token);
>> +                     goto err;
>> +             }
>> +
>> +             mask  = val & 0xFF;
>> +             src = (val & 0XFF00) >> 8;
>> +             iwmct_log_set_filter(src, mask);
>> +     }
>> +
>> +     kfree(str_buf);
>> +     return count;
>> +
>> +err:
>> +     kfree(str_buf);
>> +     return -EAGAIN;
>> +}
>> +
>> +ssize_t show_iwmct_log_level_fw(struct device *d,
>> +                     struct device_attribute *attr, char *buf)
>> +{
>> +     struct iwmct_priv *priv = d->driver_data;
>> +     char *str_buf;
>> +     int buf_size;
>> +     ssize_t ret = -EAGAIN;
>> +
>> +     buf_size = (LOG_SRC_FORMAT * FW_LOG_SRC_MAX) + 2;
>> +
>> +     str_buf = kzalloc(buf_size, GFP_KERNEL);
>> +     if (!str_buf) {
>> +             LOG_ERROR(priv, DEBUGFS,
>> +                     "failed to allocate %d bytes\n", buf_size);
>> +             goto exit;
>> +     }
>> +
>> +     if (log_get_fw_filter_str(str_buf, buf_size) < 0)
>> +             goto exit;
>> +
>> +     ret = sprintf(buf, "%s", str_buf);
>> +
>> +exit:
>> +     kfree(str_buf);
>> +     return ret;
>> +}
>> +
>> +ssize_t store_iwmct_log_level_fw(struct device *d,
>> +                     struct device_attribute *attr,
>> +                     const char *buf, size_t count)
>> +{
>> +     struct iwmct_priv *priv = d->driver_data;
>> +     char *token, *str_buf = NULL;
>> +     long val;
>> +     u8 src, mask;
>> +     struct top_msg cmd;
>> +     u16 cmdlen = 0;
>> +     int i, rc;
>> +
>> +     if (!count)
>> +             goto err;
>> +
>> +     str_buf = kzalloc(count, GFP_KERNEL);
>> +     if (!str_buf) {
>> +             LOG_ERROR(priv, DEBUGFS,
>> +                     "failed to allocate %zd bytes\n", count);
>> +             goto err;
>> +     }
>> +
>> +     memcpy(str_buf, buf, count);
>> +
>> +     cmd.hdr.type = COMM_TYPE_H2D;
>> +     cmd.hdr.category = COMM_CATEGORY_DEBUG;
>> +     cmd.hdr.opcode = CMD_DBG_LOG_LEVEL;
>> +
>> +     for (i = 0; ((token = strsep(&str_buf, ",")) != NULL) &&
>> +                  (i < FW_LOG_SRC_MAX); i++) {
>> +
>> +             while (isspace(*token))
>> +                     ++token;
>> +
>> +             if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
>> +                     LOG_ERROR(priv, DEBUGFS,
>> +                               "failed to convert string to long %s\n",
>> +                               token);
>> +                     goto err;
>> +             }
>> +
>> +             mask  = val & 0xFF; /* LSB */
>> +             src = (val & 0XFF00) >> 8; /* 2nd least significant byte. */
>> +             iwmct_log_set_fw_filter(src, mask);
>> +
>> +             cmd.u.logdefs[i].logsource = src;
>> +             cmd.u.logdefs[i].sevmask = mask;
>> +     }
>> +
>> +     cmd.hdr.length = cpu_to_le16(i * sizeof(cmd.u.logdefs[0]));
>> +     cmdlen = (i * sizeof(cmd.u.logdefs[0]) + sizeof(cmd.hdr));
>> +
>> +     rc = iwmct_send_hcmd(priv, (u8 *) &cmd, cmdlen);
>> +     if (rc) {
>> +             LOG_ERROR(priv, DEBUGFS,
>> +                       "Failed to send %d bytes of fwcmd, rc=%d\n",
>> +                       cmdlen, rc);
>> +             goto err;
>> +     } else
>> +             LOG_INFO(priv, DEBUGFS, "fwcmd sent (%d bytes)\n", cmdlen);
>> +
>> +     kfree(str_buf);
>> +     return count;
>> +
>> +err:
>> +     kfree(str_buf);
>> +     return -EAGAIN;
>> +}
>> +
>> diff --git a/drivers/misc/iwmc3200top/log.h b/drivers/misc/iwmc3200top/log.h
>> new file mode 100644
>> index 0000000..aba8121
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/log.h
>> @@ -0,0 +1,158 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/log.h
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#ifndef __LOG_H__
>> +#define __LOG_H__
>> +
>> +
>> +/* log severity:
>> + * The log levels here match FW log levels
>> + * so values need to stay as is */
>> +#define LOG_SEV_CRITICAL             0
>> +#define LOG_SEV_ERROR                        1
>> +#define LOG_SEV_WARNING                      2
>> +#define LOG_SEV_INFO                 3
>> +#define LOG_SEV_INFOEX                       4
>> +
>> +#define LOG_SEV_FILTER_ALL           \
>> +     (BIT(LOG_SEV_CRITICAL) |        \
>> +      BIT(LOG_SEV_ERROR)    |        \
>> +      BIT(LOG_SEV_WARNING)  |        \
>> +      BIT(LOG_SEV_INFO)     |        \
>> +      BIT(LOG_SEV_INFOEX))
>> +
>> +/* log source */
>> +#define LOG_SRC_INIT                 0
>> +#define LOG_SRC_DEBUGFS                      1
>> +#define LOG_SRC_FW_DOWNLOAD          2
>> +#define LOG_SRC_FW_MSG                       3
>> +#define LOG_SRC_TST                  4
>> +#define LOG_SRC_IRQ                  5
>> +
>> +#define      LOG_SRC_MAX                     6
>> +#define      LOG_SRC_ALL                     0xFF
>> +
>> +/**
>> + * Default intitialization runtime log level
>> + */
>> +#ifndef LOG_SEV_FILTER_RUNTIME
>> +#define LOG_SEV_FILTER_RUNTIME                       \
>> +     (BIT(LOG_SEV_CRITICAL)  |               \
>> +      BIT(LOG_SEV_ERROR)     |               \
>> +      BIT(LOG_SEV_WARNING))
>> +#endif
>> +
>> +#ifndef FW_LOG_SEV_FILTER_RUNTIME
>> +#define FW_LOG_SEV_FILTER_RUNTIME    LOG_SEV_FILTER_ALL
>> +#endif
>> +
>> +#ifdef CONFIG_IWMC3200TOP_DEBUG
>> +/**
>> + * Log macros
>> + */
>> +
>> +#define priv2dev(priv) (&(priv->func)->dev)
>> +
>> +#define LOG_CRITICAL(priv, src, fmt, args...)                                \
>> +do {                                                                 \
>> +     if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_CRITICAL))     \
>> +             dev_crit(priv2dev(priv), "%s %d: " fmt,                 \
>> +                     __func__, __LINE__, ##args);                    \
>> +} while (0)
>> +
>> +#define LOG_ERROR(priv, src, fmt, args...)                           \
>> +do {                                                                 \
>> +     if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_ERROR))        \
>> +             dev_err(priv2dev(priv), "%s %d: " fmt,                  \
>> +                     __func__, __LINE__, ##args);                    \
>> +} while (0)
>> +
>> +#define LOG_WARNING(priv, src, fmt, args...)                         \
>> +do {                                                                 \
>> +     if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_WARNING))      \
>> +             dev_warn(priv2dev(priv), "%s %d: " fmt,                 \
>> +                      __func__, __LINE__, ##args);                   \
>> +} while (0)
>> +
>> +#define LOG_INFO(priv, src, fmt, args...)                            \
>> +do {                                                                 \
>> +     if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFO))         \
>> +             dev_info(priv2dev(priv), "%s %d: " fmt,                 \
>> +                      __func__, __LINE__, ##args);                   \
>> +} while (0)
>> +
>> +#define LOG_INFOEX(priv, src, fmt, args...)                          \
>> +do {                                                                 \
>> +     if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))       \
>> +             dev_dbg(priv2dev(priv), "%s %d: " fmt,                  \
>> +                      __func__, __LINE__, ##args);                   \
>> +} while (0)
>> +
>> +#define LOG_HEXDUMP(src, ptr, len)                                   \
>> +do {                                                                 \
>> +     if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))       \
>> +             print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,        \
>> +                             16, 1, ptr, len, false);                \
>> +} while (0)
>> +
>> +void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len);
>> +
>> +extern u8 iwmct_logdefs[];
>> +
>> +int iwmct_log_set_filter(u8 src, u8 logmask);
>> +int iwmct_log_set_fw_filter(u8 src, u8 logmask);
>> +
>> +ssize_t show_iwmct_log_level(struct device *d,
>> +                     struct device_attribute *attr, char *buf);
>> +ssize_t store_iwmct_log_level(struct device *d,
>> +                     struct device_attribute *attr,
>> +                     const char *buf, size_t count);
>> +ssize_t show_iwmct_log_level_fw(struct device *d,
>> +                     struct device_attribute *attr, char *buf);
>> +ssize_t store_iwmct_log_level_fw(struct device *d,
>> +                     struct device_attribute *attr,
>> +                     const char *buf, size_t count);
>> +
>> +#else
>> +
>> +#define LOG_CRITICAL(priv, src, fmt, args...)
>> +#define LOG_ERROR(priv, src, fmt, args...)
>> +#define LOG_WARNING(priv, src, fmt, args...)
>> +#define LOG_INFO(priv, src, fmt, args...)
>> +#define LOG_INFOEX(priv, src, fmt, args...)
>> +#define LOG_HEXDUMP(src, ptr, len)
>> +
>> +static inline void iwmct_log_top_message(struct iwmct_priv *priv,
>> +                                      u8 *buf, int len) {}
>> +static inline int iwmct_log_set_filter(u8 src, u8 logmask) { return 0; }
>> +static inline int iwmct_log_set_fw_filter(u8 src, u8 logmask) { return 0; }
>> +
>> +#endif /* CONFIG_IWMC3200TOP_DEBUG */
>> +
>> +int log_get_filter_str(char *buf, int size);
>> +int log_get_fw_filter_str(char *buf, int size);
>> +
>> +#endif /* __LOG_H__ */
>
> Seriously. Please just use dynamic_printk and lets remove all this log
> infrastructure. It is way too much overhead for too little benefit.
>
>> diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c
>> new file mode 100644
>> index 0000000..09f8d06
>> --- /dev/null
>> +++ b/drivers/misc/iwmc3200top/main.c
>> @@ -0,0 +1,702 @@
>> +/*
>> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
>> + * drivers/misc/iwmc3200top/main.c
>> + *
>> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License version
>> + * 2 as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> + * 02110-1301, USA.
>> + *
>> + *
>> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
>> + *  -
>> + *
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/mmc/sdio_ids.h>
>> +#include <linux/mmc/sdio_func.h>
>> +#include <linux/mmc/sdio.h>
>> +
>> +#include "iwmc3200top.h"
>> +#include "log.h"
>> +#include "fw-msg.h"
>> +#include "debugfs.h"
>> +
>> +
>> +#define DRIVER_DESCRIPTION "Intel(R) IWMC 3200 Top Driver"
>> +#define DRIVER_COPYRIGHT "Copyright (c) 2008 Intel Corporation."
>> +
>> +#define IWMCT_VERSION "0.1.62"
>> +
>> +#ifdef REPOSITORY_LABEL
>> +#define RL REPOSITORY_LABEL
>> +#else
>> +#define RL ""
>> +#endif
>> +
>> +#ifdef CONFIG_IWMC3200TOP_DEBUG
>> +#define VD "-d"
>> +#else
>> +#define VD
>> +#endif
>> +
>> +#define DRIVER_VERSION IWMCT_VERSION "-"  __stringify(RL) VD
>> +
>> +MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
>> +MODULE_VERSION(DRIVER_VERSION);
>> +MODULE_LICENSE("GPL");
>> +MODULE_AUTHOR(DRIVER_COPYRIGHT);
>> +
>> +
>> +#ifndef SDIO_DEVICE_ID_INTEL_IWMC3200TOP
>> +#define SDIO_DEVICE_ID_INTEL_IWMC3200TOP     0x1404
>> +#endif
>> +
>> +/*
>> + * This workers main task is to wait for OP_OPR_ALIVE
>> + * from TOP FW until ALIVE_MSG_TIMOUT timeout is elapsed.
>> + * When OP_OPR_ALIVE received it will issue
>> + * a call to "bus_rescan_devices".
>> + */
>> +static void iwmct_rescan_worker(struct work_struct *ws)
>> +{
>> +     struct iwmct_priv *priv;
>> +     int ret;
>> +
>> +     priv = container_of(ws, struct iwmct_priv, bus_rescan_worker);
>> +
>> +     LOG_INFO(priv, FW_MSG, "Calling bus_rescan\n");
>> +
>> +     ret = bus_rescan_devices(priv->func->dev.bus);
>> +     if (ret < 0)
>> +             LOG_INFO(priv, FW_DOWNLOAD, "bus_rescan_devices FAILED!!!\n");
>> +}
>> +
>> +static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg)
>> +{
>> +     switch (msg->hdr.opcode) {
>> +     case OP_OPR_ALIVE:
>> +             LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n");
>> +             queue_work(priv->bus_rescan_wq, &priv->bus_rescan_worker);
>> +             break;
>> +     default:
>> +             LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n",
>> +                     msg->hdr.opcode);
>> +             break;
>> +     }
>> +}
>> +
>> +
>> +static void handle_top_message(struct iwmct_priv *priv, u8 *buf, int len)
>> +{
>> +     struct top_msg *msg;
>> +
>> +     msg = (struct top_msg *)buf;
>> +
>> +     if (msg->hdr.type != COMM_TYPE_D2H) {
>> +             LOG_ERROR(priv, FW_MSG,
>> +                     "Message from TOP with invalid message type 0x%X\n",
>> +                     msg->hdr.type);
>> +             return;
>> +     }
>> +
>> +     if (len < sizeof(msg->hdr)) {
>> +             LOG_ERROR(priv, FW_MSG,
>> +                     "Message from TOP is too short for message header "
>> +                     "received %d bytes, expected at least %zd bytes\n",
>> +                     len, sizeof(msg->hdr));
>> +             return;
>> +     }
>> +
>> +     if (len < le16_to_cpu(msg->hdr.length) + sizeof(msg->hdr)) {
>> +             LOG_ERROR(priv, FW_MSG,
>> +                     "Message length (%d bytes) is shorter than "
>> +                     "in header (%d bytes)\n",
>> +                     len, le16_to_cpu(msg->hdr.length));
>> +             return;
>> +     }
>> +
>> +     switch (msg->hdr.category) {
>> +     case COMM_CATEGORY_OPERATIONAL:
>> +             op_top_message(priv, (struct top_msg *)buf);
>> +             break;
>> +
>> +     case COMM_CATEGORY_DEBUG:
>> +     case COMM_CATEGORY_TESTABILITY:
>> +     case COMM_CATEGORY_DIAGNOSTICS:
>> +             iwmct_log_top_message(priv, buf, len);
>> +             break;
>> +
>> +     default:
>> +             LOG_ERROR(priv, FW_MSG,
>> +                     "Message from TOP with unknown category 0x%X\n",
>> +                     msg->hdr.category);
>> +             break;
>> +     }
>> +}
>> +
>> +int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len)
>> +{
>> +     int ret;
>> +     u8 *buf;
>> +
>> +     LOG_INFOEX(priv, FW_MSG, "Sending hcmd:\n");
>> +
>> +     /* add padding to 256 for IWMC */
>> +     ((struct top_msg *)cmd)->hdr.flags |= CMD_FLAG_PADDING_256;
>> +
>> +     LOG_HEXDUMP(FW_MSG, cmd, len);
>> +
>> +     if (len > FW_HCMD_BLOCK_SIZE) {
>> +             LOG_ERROR(priv, FW_MSG, "size %d exceeded hcmd max size %d\n",
>> +                       len, FW_HCMD_BLOCK_SIZE);
>> +             return -1;
>> +     }
>> +
>> +     buf = kzalloc(FW_HCMD_BLOCK_SIZE, GFP_KERNEL);
>> +     if (!buf) {
>> +             LOG_ERROR(priv, FW_MSG, "kzalloc error, buf size %d\n",
>> +                       FW_HCMD_BLOCK_SIZE);
>> +             return -1;
>> +     }
>> +
>> +     memcpy(buf, cmd, len);
>> +
>> +     sdio_claim_host(priv->func);
>> +     ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, buf,
>> +                            FW_HCMD_BLOCK_SIZE);
>> +     sdio_release_host(priv->func);
>> +
>> +     kfree(buf);
>> +     return ret;
>> +}
>> +
>> +int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
>> +     void *src, int count)
>> +{
>> +     int ret;
>> +
>> +     sdio_claim_host(priv->func);
>> +     ret = sdio_memcpy_toio(priv->func, addr, src, count);
>> +     sdio_release_host(priv->func);
>> +
>> +     return ret;
>> +}
>> +
>> +static void iwmct_irq_read_worker(struct work_struct *ws)
>> +{
>> +     struct iwmct_priv *priv;
>> +     struct iwmct_work_struct *read_req;
>> +     __le32 *buf = NULL;
>> +     int ret, val, i;
>> +     int iosize;
>> +     u32 barker;
>> +
>> +     priv = container_of(ws, struct iwmct_priv, isr_worker);
>> +
>> +     LOG_INFO(priv, IRQ, "enter iwmct_irq_read_worker %p\n", ws);
>> +
>> +     /* --------------------- Handshake with device -------------------- */
>> +     sdio_claim_host(priv->func);
>> +
>> +     /* all list manipulations have to be protected by
>> +      * sdio_claim_host/sdio_release_host */
>> +     if (list_empty(&priv->read_req_list)) {
>> +             LOG_ERROR(priv, IRQ, "read_req_list empty in read worker\n");
>> +             goto exit_release;
>> +     }
>> +
>> +     read_req = list_entry(priv->read_req_list.next,
>> +                           struct iwmct_work_struct, list);
>> +
>> +     list_del(&read_req->list);
>> +     iosize = read_req->iosize;
>> +     kfree(read_req);
>> +
>> +     buf = kzalloc(iosize, GFP_KERNEL);
>> +     if (!buf) {
>> +             LOG_ERROR(priv, IRQ, "kzalloc error, buf size %d\n", iosize);
>> +             goto exit_release;
>> +     }
>> +
>> +     LOG_INFO(priv, IRQ, "iosize=%d, buf=%p, func=%d\n",
>> +                             iosize, buf, priv->func->num);
>> +
>> +     /* read from device */
>> +     ret = sdio_memcpy_fromio(priv->func, buf, IWMC_SDIO_DATA_ADDR, iosize);
>> +     if (ret) {
>> +             LOG_ERROR(priv, IRQ, "error %d reading buffer\n", ret);
>> +             goto exit_release;
>> +     }
>> +
>> +     LOG_HEXDUMP(IRQ, (u8 *)buf, iosize);
>> +
>> +     barker = le32_to_cpu(buf[0]);
>> +     if (barker != IWMC_BARKER_ACK &&
>> +        (barker & BARKER_DNLOAD_BARKER_MSK) != IWMC_BARKER_REBOOT) {
>> +             /* Handle Top Commhub message.
>> +              * Current handling - treat all message as
>> +              * logger messages and print the context as a string. */
>> +             sdio_release_host(priv->func);
>> +             handle_top_message(priv, (u8 *)buf, iosize);
>> +             goto exit;
>> +     }
>> +
>> +     /* verify basic barker sanity */
>> +     for (i = 1; i < 4; i++)
>> +             if (buf[i] != buf[0]) {
>> +                     LOG_ERROR(priv, IRQ, "Corrupted barker,"
>> +                                          "buf[%d]=%x buf[0]=%x\n",
>> +                                          i, buf[i], buf[0]);
>> +                     goto exit_release;
>> +             }
>> +
>> +     val = atomic_read(&priv->dev_sync);
>> +
>> +     switch (val) {
>> +     case 0:
>> +             /* we expect to recieve REBOOT BARKER */
>> +             if ((barker & BARKER_DNLOAD_BARKER_MSK) != IWMC_BARKER_REBOOT) {
>> +                     LOG_ERROR(priv, IRQ, "Expecting for reboot barker %x,"
>> +                                     "but got %x\n",
>> +                                     IWMC_BARKER_REBOOT,
>> +                                     (barker & BARKER_DNLOAD_BARKER_MSK));
>> +                     goto exit_release;
>> +             }
>> +
>> +             LOG_INFO(priv, IRQ, "Recieved reboot barker: %x\n", barker);
>> +             priv->barker = barker;
>> +
>> +             if (barker & BARKER_DNLOAD_SYNC_MSK) {
>> +                     /* Send the same barker back */
>> +                     ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR,
>> +                                            buf, iosize);
>> +                     if (ret) {
>> +                             LOG_ERROR(priv, IRQ,
>> +                                      "error %d echoing barker\n", ret);
>> +                             goto exit_release;
>> +                     }
>> +                     LOG_INFO(priv, IRQ, "Echoing barker to device\n");
>> +                     atomic_inc(&priv->dev_sync);
>> +                     goto exit_release;
>> +             }
>> +             break;
>> +
>> +     case 1:
>> +             /* we expect to recieve ACK BARKER */
>> +             if (barker != IWMC_BARKER_ACK) {
>> +                     LOG_INFO(priv, IRQ, "Expecting for ACK barker[%x],"
>> +                              "got this instead %x\n",
>> +                              IWMC_BARKER_ACK, barker);
>> +                     goto exit_release;
>> +             }
>> +             kfree(buf);
>> +             atomic_set(&priv->dev_sync, 0);
>> +             atomic_set(&priv->reset, 0);
>> +             break;
>> +
>> +     default:
>> +             LOG_INFO(priv, IRQ, "Wrong dev_sync %d\n", val);
>> +             break;
>> +     }
>> +
>> +     sdio_release_host(priv->func);
>> +
>> +
>> +     LOG_INFO(priv, IRQ, "barker download request 0x%x is:\n", priv->barker);
>> +     LOG_INFO(priv, IRQ, "*******  Top FW %s requested ********\n",
>> +                     (priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
>> +     LOG_INFO(priv, IRQ, "*******  GPS FW %s requested ********\n",
>> +                     (priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
>> +     LOG_INFO(priv, IRQ, "*******  BT FW %s requested ********\n",
>> +                     (priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");
>> +
>> +     if (priv->dbg.fw_download)
>> +             iwmct_fw_load(priv);
>> +     else
>> +             LOG_ERROR(priv, IRQ, "FW download not allowed\n");
>> +
>> +     return;
>> +
>> +exit_release:
>> +     sdio_release_host(priv->func);
>> +exit:
>> +     kfree(buf);
>> +     LOG_INFO(priv, IRQ, "exit iwmct_irq_read_worker\n");
>> +}
>> +
>> +static void iwmct_irq(struct sdio_func *func)
>> +{
>> +     struct iwmct_priv *priv;
>> +     int val, ret;
>> +     int iosize;
>> +     int addr = IWMC_SDIO_INTR_GET_SIZE_ADDR;
>> +     struct iwmct_work_struct *read_req;
>> +
>> +     priv = sdio_get_drvdata(func);
>> +
>> +     LOG_INFO(priv, IRQ, "enter iwmct_irq\n");
>> +
>> +     /* read the function's status register */
>> +     val = sdio_readb(func, IWMC_SDIO_INTR_STATUS_ADDR, &ret);
>> +
>> +     LOG_INFO(priv, IRQ, "iir value = %d, ret=%d\n", val, ret);
>> +
>> +     if (!val) {
>> +             LOG_ERROR(priv, IRQ, "iir = 0, exiting ISR\n");
>> +             goto exit_clear_intr;
>> +     }
>> +
>> +
>> +     /*
>> +      * read 2 bytes of the transaction size
>> +      * IMPORTANT: sdio transaction size has to be read before clearing
>> +      * sdio interrupt!!!
>> +      */
>> +     val = sdio_readb(priv->func, addr++, &ret);
>> +     iosize = val;
>> +     val = sdio_readb(priv->func, addr++, &ret);
>> +     iosize += val << 8;
>> +
>> +     LOG_INFO(priv, IRQ, "READ size %d\n", iosize);
>> +
>> +     if (iosize == 0) {
>> +             LOG_ERROR(priv, IRQ, "READ size %d, exiting ISR\n", iosize);
>> +             goto exit_clear_intr;
>> +     }
>> +
>> +     /* allocate a work structure to pass iosize to the worker */
>> +     read_req = kzalloc(sizeof(struct iwmct_work_struct), GFP_KERNEL);
>> +     if (!read_req) {
>> +             LOG_ERROR(priv, IRQ, "failed to allocate read_req, exit ISR\n");
>> +             goto exit_clear_intr;
>> +     }
>> +
>> +     INIT_LIST_HEAD(&read_req->list);
>> +     read_req->iosize = iosize;
>> +
>> +     list_add_tail(&priv->read_req_list, &read_req->list);
>> +
>> +     /* clear the function's interrupt request bit (write 1 to clear) */
>> +     sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
>> +
>> +     queue_work(priv->wq, &priv->isr_worker);
>> +
>> +     LOG_INFO(priv, IRQ, "exit iwmct_irq\n");
>> +
>> +     return;
>> +
>> +exit_clear_intr:
>> +     /* clear the function's interrupt request bit (write 1 to clear) */
>> +     sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
>> +}
>> +
>> +
>> +static int blocks;
>> +module_param(blocks, int, 0604);
>> +MODULE_PARM_DESC(blocks, "max_blocks_to_send");
>> +
>> +static int dump;
>> +module_param(dump, bool, 0604);
>> +MODULE_PARM_DESC(dump, "dump_hex_content");
>> +
>> +static int jump = 1;
>> +module_param(jump, bool, 0604);
>> +
>> +static int direct = 1;
>> +module_param(direct, bool, 0604);
>> +
>> +static int checksum = 1;
>> +module_param(checksum, bool, 0604);
>> +
>> +static int fw_download = 1;
>> +module_param(fw_download, bool, 0604);
>> +
>> +static int block_size = IWMC_SDIO_BLK_SIZE;
>> +module_param(block_size, int, 0404);
>> +
>> +static int download_trans_blks = IWMC_DEFAULT_TR_BLK;
>> +module_param(download_trans_blks, int, 0604);
>> +
>> +static int rubbish_barker;
>> +module_param(rubbish_barker, bool, 0604);
>
> Most of them are missing descriptions. And do we really need them? What
> cases are they trying to work around?
>
>> +
>> +#ifdef CONFIG_IWMC3200TOP_DEBUG
>> +static int log_level[LOG_SRC_MAX];
>> +static unsigned int log_level_argc;
>> +module_param_array(log_level, int, &log_level_argc, 0604);
>> +MODULE_PARM_DESC(log_level, "log_level");
>> +
>> +static int log_level_fw[FW_LOG_SRC_MAX];
>> +static unsigned int log_level_fw_argc;
>> +module_param_array(log_level_fw, int, &log_level_fw_argc, 0604);
>> +MODULE_PARM_DESC(log_level_fw, "log_level_fw");
>> +#endif
>> +
>> +void iwmct_dbg_init_params(struct iwmct_priv *priv)
>> +{
>> +#ifdef CONFIG_IWMC3200TOP_DEBUG
>> +     int i;
>> +
>> +     for (i = 0; i < log_level_argc; i++) {
>> +             dev_notice(&priv->func->dev, "log_level[%d]=0x%X\n",
>> +                                             i, log_level[i]);
>> +             iwmct_log_set_filter((log_level[i] >> 8) & 0xFF,
>> +                            log_level[i] & 0xFF);
>> +     }
>> +     for (i = 0; i < log_level_fw_argc; i++) {
>> +             dev_notice(&priv->func->dev, "log_level_fw[%d]=0x%X\n",
>> +                                             i, log_level_fw[i]);
>> +             iwmct_log_set_fw_filter((log_level_fw[i] >> 8) & 0xFF,
>> +                               log_level_fw[i] & 0xFF);
>> +     }
>> +#endif
>> +
>> +     priv->dbg.blocks = blocks;
>> +     LOG_INFO(priv, INIT, "blocks=%d\n", blocks);
>> +     priv->dbg.dump = (bool)dump;
>> +     LOG_INFO(priv, INIT, "dump=%d\n", dump);
>> +     priv->dbg.jump = (bool)jump;
>> +     LOG_INFO(priv, INIT, "jump=%d\n", jump);
>> +     priv->dbg.direct = (bool)direct;
>> +     LOG_INFO(priv, INIT, "direct=%d\n", direct);
>> +     priv->dbg.checksum = (bool)checksum;
>> +     LOG_INFO(priv, INIT, "checksum=%d\n", checksum);
>> +     priv->dbg.fw_download = (bool)fw_download;
>> +     LOG_INFO(priv, INIT, "fw_download=%d\n", fw_download);
>> +     priv->dbg.block_size = block_size;
>> +     LOG_INFO(priv, INIT, "block_size=%d\n", block_size);
>> +     priv->dbg.download_trans_blks = download_trans_blks;
>> +     LOG_INFO(priv, INIT, "download_trans_blks=%d\n", download_trans_blks);
>> +}
>> +
>> +/*****************************************************************************
>> + *
>> + * sysfs attributes
>> + *
>> + *****************************************************************************/
>> +static ssize_t show_iwmct_fw_version(struct device *d,
>> +                               struct device_attribute *attr, char *buf)
>> +{
>> +     return sprintf(buf, "%s\n",
>> +                    ((struct iwmct_priv *)d->driver_data)->dbg.label_fw);
>> +}
>> +static DEVICE_ATTR(cc_label_fw, S_IRUGO, show_iwmct_fw_version, NULL);
>> +
>> +#ifdef CONFIG_IWMC3200TOP_DEBUG
>> +static DEVICE_ATTR(log_level, S_IWUSR | S_IRUGO,
>> +                show_iwmct_log_level, store_iwmct_log_level);
>> +static DEVICE_ATTR(log_level_fw, S_IWUSR | S_IRUGO,
>> +                show_iwmct_log_level_fw, store_iwmct_log_level_fw);
>> +#endif
>
> First module parameters and now device attributes. Why?
>
>> +
>> +static struct attribute *iwmct_sysfs_entries[] = {
>> +     &dev_attr_cc_label_fw.attr,
>> +#ifdef CONFIG_IWMC3200TOP_DEBUG
>> +     &dev_attr_log_level.attr,
>> +     &dev_attr_log_level_fw.attr,
>> +#endif
>> +     NULL
>> +};
>> +
>> +static struct attribute_group iwmct_attribute_group = {
>> +     .name = NULL,           /* put in device directory */
>> +     .attrs = iwmct_sysfs_entries,
>> +};
>> +
>> +
>> +static int iwmct_probe(struct sdio_func *func,
>> +                        const struct sdio_device_id *id)
>> +{
>> +     struct iwmct_priv *priv;
>> +     int ret;
>> +     int val = 1;
>> +     int addr = IWMC_SDIO_INTR_ENABLE_ADDR;
>> +
>> +     dev_info(&func->dev, "enter iwmct_probe\n");
>> +
>> +     dev_info(&func->dev, "IRQ polling period id %u msecs, HZ is %d\n",
>> +             jiffies_to_msecs(2147483647), HZ);
>
> This is debug code. Don't use dev_info().
>
>> +
>> +     priv = kzalloc(sizeof(struct iwmct_priv), GFP_KERNEL);
>> +     if (!priv) {
>> +             dev_err(&func->dev, "kzalloc error\n");
>> +             return -ENOMEM;
>> +     }
>> +     priv->func = func;
>> +     sdio_set_drvdata(func, priv);
>> +
>> +     LOG_INFO(priv, INIT, "HIDR supported\n");
>> +
>> +     /* create drivers work queue */
>> +     priv->wq = create_workqueue(DRV_NAME "_wq");
>> +     priv->bus_rescan_wq = create_workqueue(DRV_NAME "_rescan_wq");
>> +     INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker);
>> +     INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker);
>> +
>> +     init_waitqueue_head(&priv->wait_q);
>> +
>> +     sdio_claim_host(func);
>> +     /* FIXME: Remove after it is fixed in the Boot ROM upgrade */
>> +     func->enable_timeout = 10;
>> +
>> +     /* In our HW, setting the block size also wakes up the boot rom. */
>> +     ret = sdio_set_block_size(func, priv->dbg.block_size);
>> +     if (ret) {
>> +             LOG_ERROR(priv, INIT,
>> +                     "sdio_set_block_size() failure: %d\n", ret);
>> +             goto error_sdio_enable;
>> +     }
>> +
>> +     ret = sdio_enable_func(func);
>> +     if (ret) {
>> +             LOG_ERROR(priv, INIT, "sdio_enable_func() failure: %d\n", ret);
>> +             goto error_sdio_enable;
>> +     }
>> +
>> +     /* init reset and dev_sync states */
>> +     atomic_set(&priv->reset, 0);
>> +     atomic_set(&priv->dev_sync, 0);
>> +
>> +     /* init read req queue */
>> +     INIT_LIST_HEAD(&priv->read_req_list);
>> +
>> +     /* process configurable parameters */
>> +     iwmct_dbg_init_params(priv);
>> +     ret = sysfs_create_group(&func->dev.kobj, &iwmct_attribute_group);
>> +     if (ret) {
>> +             LOG_ERROR(priv, INIT, "Failed to register attributes and "
>> +                      "initialize module_params\n");
>> +             goto error_dev_attrs;
>> +     }
>> +
>> +     iwmct_dbgfs_register(priv, DRV_NAME);
>> +
>> +     if (!priv->dbg.direct && priv->dbg.download_trans_blks > 8) {
>> +             LOG_INFO(priv, INIT,
>> +                      "Reducing transaction to 8 blocks = 2K (from %d)\n",
>> +                      priv->dbg.download_trans_blks);
>> +             priv->dbg.download_trans_blks = 8;
>> +     }
>> +     priv->trans_len = priv->dbg.download_trans_blks * priv->dbg.block_size;
>> +     LOG_INFO(priv, INIT, "Transaction length = %d\n", priv->trans_len);
>> +
>> +     ret = sdio_claim_irq(func, iwmct_irq);
>> +     if (ret) {
>> +             LOG_ERROR(priv, INIT, "sdio_claim_irq() failure: %d\n", ret);
>> +             goto error_claim_irq;
>> +     }
>> +
>> +
>> +     /* Enable function's interrupt */
>> +     sdio_writeb(priv->func, val, addr, &ret);
>> +     if (ret) {
>> +             LOG_ERROR(priv, INIT, "Failure writing to "
>> +                       "Interrupt Enable Register (%d): %d\n", addr, ret);
>> +             goto error_enable_int;
>> +     }
>> +
>> +     sdio_release_host(func);
>> +
>> +     LOG_INFO(priv, INIT, "exit iwmct_probe\n");
>> +
>> +     return ret;
>> +
>> +error_enable_int:
>> +     sdio_release_irq(func);
>> +error_claim_irq:
>> +     sdio_disable_func(func);
>> +error_dev_attrs:
>> +     iwmct_dbgfs_unregister(priv->dbgfs);
>> +     sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
>> +error_sdio_enable:
>> +     sdio_release_host(func);
>> +     return ret;
>> +}
>> +
>> +static void iwmct_remove(struct sdio_func *func)
>> +{
>> +     struct iwmct_work_struct *read_req;
>> +     struct iwmct_priv *priv = sdio_get_drvdata(func);
>> +
>> +     priv = sdio_get_drvdata(func);
>> +
>> +     LOG_INFO(priv, INIT, "enter\n");
>> +
>> +     sdio_claim_host(func);
>> +     sdio_release_irq(func);
>> +     sdio_release_host(func);
>> +
>> +     /* Safely destroy osc workqueue */
>> +     destroy_workqueue(priv->bus_rescan_wq);
>> +     destroy_workqueue(priv->wq);
>> +
>> +     sdio_claim_host(func);
>> +     sdio_disable_func(func);
>> +     sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
>> +     iwmct_dbgfs_unregister(priv->dbgfs);
>> +     sdio_release_host(func);
>> +
>> +     /* free read requests */
>> +     while (!list_empty(&priv->read_req_list)) {
>> +             read_req = list_entry(priv->read_req_list.next,
>> +                     struct iwmct_work_struct, list);
>> +
>> +             list_del(&read_req->list);
>> +             kfree(read_req);
>> +     }
>> +
>> +     kfree(priv);
>> +}
>> +
>> +
>> +static const struct sdio_device_id iwmct_ids[] = {
>> +     { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, SDIO_DEVICE_ID_INTEL_IWMC3200TOP)},
>> +     { /* end: all zeroes */ },
>> +};
>> +
>> +MODULE_DEVICE_TABLE(sdio, iwmct_ids);
>> +
>> +static struct sdio_driver iwmct_driver = {
>> +     .probe          = iwmct_probe,
>> +     .remove         = iwmct_remove,
>> +     .name           = DRV_NAME,
>> +     .id_table       = iwmct_ids,
>> +};
>> +
>> +static int __init iwmct_init(void)
>> +{
>> +     int rc;
>> +
>> +     /* Default log filter settings */
>> +     iwmct_log_set_filter(LOG_SRC_ALL, LOG_SEV_FILTER_RUNTIME);
>> +     iwmct_log_set_filter(LOG_SRC_FW_MSG, LOG_SEV_FILTER_ALL);
>> +     iwmct_log_set_fw_filter(LOG_SRC_ALL, FW_LOG_SEV_FILTER_RUNTIME);
>> +
>> +     rc = sdio_register_driver(&iwmct_driver);
>> +
>> +     return rc;
>> +}
>
> Actually return sdio_register_driver() would do the same trick.
>
>> +
>> +static void __exit iwmct_exit(void)
>> +{
>> +     sdio_unregister_driver(&iwmct_driver);
>> +}
>> +
>> +module_init(iwmct_init);
>> +module_exit(iwmct_exit);
>> +
>
> At some point I got lost in this code. It contains more debug statements
> and infrastructure than actual code as it seems. Can you please clean
> this up. I mentioned it above. Just use dynamic_printk and you should be
> have something clean and simple.
>
> Regards
>
> Marcel
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: deauthentication and disassociation nl80211 commands
From: Johannes Berg @ 2009-10-10 16:24 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: hostap@lists.shmoo.com, linux-wireless
In-Reply-To: <1254708707.24430.68.camel@maxim-laptop>

[-- Attachment #1: Type: text/plain, Size: 1174 bytes --]

On Mon, 2009-10-05 at 04:11 +0200, Maxim Levitsky wrote:

> My hacky patch that was rejected on the grounds that it is not right to
> introduce the driver dependent behavior might actually be the correct
> solution. It just makes the wpa_supplicant_disassociate do both
> disassociation and deauthentication, as was always assumed by the
> wpa_supplicant core.

Jouni just wanted to have what he felt was a workaround in
driver_nl80211.c rather than the core code.

> Or kernel should became smarter and do the work for wpa_supplicant. 

I still disagree. Why should the kernel deauthenticate when userspace
disassociated.

On the other hand, I think Jouni's argument is that you should be able
to authenticate (force an auth frame exchange) even while authenticated.
I don't really disagree with that all that much, but I'm not sure how to
cleanly fit it in. mac80211 would have to reset the auth state without
sending a deauth.

johannes

(NB: I'm off to Japan on Monday. Sorry I've been slow with email, but
had lots of stuff to do and then planning the next trip, I hope it'll
improve once I return on the 22nd -- well after the weekend then)

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: deauthentication and disassociation nl80211 commands
From: John Klehm @ 2009-10-10 16:04 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: hostap@lists.shmoo.com, linux-wireless
In-Reply-To: <1255146340.3542.10.camel@maxim-laptop>

On Fri, Oct 9, 2009 at 10:45 PM, Maxim Levitsky <maximlevitsky@gmail.com> wrote:
>
> Nobody uses driver_nl80211 but me?
>

I do and I'm sure there are more people like me that get great use out
of the older working version.

Of course Id love to have an updated version but I understand that if
I don't have the time to write it then it makes it hard to complain :P

I (and others I'm sure) appreciate your efforts to document what needs
to be fixed Maxim.  No doubt useful to the person that finally takes a
crack at the nl80211 code.

Cheers,
--John Klehm

^ permalink raw reply

* Re: 2.6.31.[12] ath5k regression
From: Bob Copeland @ 2009-10-10 13:31 UTC (permalink / raw)
  To: Richard Zidlicky; +Cc: linux-wireless
In-Reply-To: <20091010125824.GA18841@hash.localnet>

On Sat, Oct 10, 2009 at 8:58 AM, Bob Copeland <me@bobcopeland.com> wrote:
>        ATH5K_TRACE(ah->ah_sc);
>
> +       if (!change_channel)
> +               printk(KERN_DEBUG "ath5k: reset with change_channel=true\n");
> +

Of course I meant change_channel=false in the format string but what's
important is how often it is printed :)

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* Re: Ath5k data aborts
From: Krzysztof Halasa @ 2009-10-10 13:05 UTC (permalink / raw)
  To: Nick Kossifidis; +Cc: linux-wireless, ath5k-devel, netdev
In-Reply-To: <40f31dec0910100356i470a93d0x3244867e1160e9df@mail.gmail.com>

Nick Kossifidis <mickflemm@gmail.com> writes:

> Interesting, can you provide us with an eeprom info dump from your
> card (using ath_info tool from madwifi svn) ?
> It seems we need to skip sleep clock operation in your case.

BTW the problem doesn't always happen immediately, sometimes it shows up
only on second or further hostapd invocation. I think in only occurs
while hostapd is starting - if it starts successfully, it works.
-- 
Krzysztof Halasa

^ permalink raw reply

* Re: 2.6.31.[12] ath5k regression
From: Bob Copeland @ 2009-10-10 12:58 UTC (permalink / raw)
  To: Richard Zidlicky; +Cc: linux-wireless
In-Reply-To: <20091009143922.GA7848@linux-m68k.org>

On Fri, Oct 09, 2009 at 04:39:22PM +0200, Richard Zidlicky wrote:
> -       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
> +       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL);
>         if (ret) {
>                 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
>                 goto err;

So, this change effectively just ensures we now program the pcu registers
at startup (every other time chan should not be null).  So my guess is
programming the pcu actually causes some problem.  Can you try this patch
instead?

Also, since you're using adhoc there may be a path that's somewhat
different from infrastructure mode, please check dmesg after applying the
patch and be sure that you only see "ath5k: reset with change_channel=true"
once per driver load.


diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
index 8fa4393..c099fa2 100644
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -1376,9 +1376,8 @@ static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
 	for (i = 0; i < size; i++) {
 		/* On channel change there is
 		 * no need to mess with PCU */
-		if (change_channel &&
-				ini_regs[i].ini_register >= AR5K_PCU_MIN &&
-				ini_regs[i].ini_register <= AR5K_PCU_MAX)
+		if (ini_regs[i].ini_register >= AR5K_PCU_MIN &&
+		    ini_regs[i].ini_register <= AR5K_PCU_MAX)
 			continue;
 
 		switch (ini_regs[i].ini_mode) {
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 3dab3d8..4b8ccbe 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -880,6 +880,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 
 	ATH5K_TRACE(ah->ah_sc);
 
+	if (!change_channel)
+		printk(KERN_DEBUG "ath5k: reset with change_channel=true\n");
+
 	s_ant = 0;
 	ee_mode = 0;
 	staid1_flags = 0;

-- 
Bob Copeland %% www.bobcopeland.com


^ permalink raw reply related

* Re: Ath5k data aborts
From: Krzysztof Halasa @ 2009-10-10 12:51 UTC (permalink / raw)
  To: Nick Kossifidis; +Cc: linux-wireless, ath5k-devel, netdev
In-Reply-To: <40f31dec0910100356i470a93d0x3244867e1160e9df@mail.gmail.com>

Nick Kossifidis <mickflemm@gmail.com> writes:

>> +#if 0
>>                AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
>>                                AR5K_PCICFG_SLEEP_CLOCK_EN);
>> +#endif

> Interesting, can you provide us with an eeprom info dump from your
> card (using ath_info tool from madwifi svn) ?
> It seems we need to skip sleep clock operation in your case.

Sure (MAC changed):

sleep_ctl reg 00000000   reset_ctl reg 00000000
 -==Device Information==-
MAC Revision: 5213A (0x59)
Device type:  3
5GHz PHY Revision: 5112B (0x36)

/============== EEPROM Information =============\
| EEPROM Version:   4.8 | EEPROM Size:  16 kbit |
| EEMAP:              1 | Reg. Domain:     0x00 |
|================= Capabilities ================|
| 802.11a Support:  yes | Turbo-A disabled: no  |
| 802.11b Support:  yes | Turbo-G disabled: no  |
| 802.11g Support:  yes | 2GHz XR disabled: no  |
| RFKill  Support:  yes | 5GHz XR disabled: no  |
| 32kHz   Crystal:  yes |                       |
\===============================================/

/=========================================================\
|          Calibration data common for all modes          |
|=========================================================|
|          CCK/OFDM gain delta:             3             |
|          CCK/OFDM power delta:           10             |
|          Scaled CCK delta:               15             |
|          2GHz Antenna gain:               1             |
|          5GHz Antenna gain:               1             |
|          Turbo 2W maximum dBm:           32             |
|          Target power start:          0x1a5             |
|          EAR Start:                   0x20f             |
\=========================================================/

/=========================================================\
|          Calibration data for 802.11a operation         |
|=========================================================|
| I power:              0x0a | Q power:              0x1e |
| Use fixed bias:       0x01 | Max turbo power:      0x20 |
| Max XR power:         0x24 | Switch Settling Time: 0x2d |
| Tx/Rx attenuation:    0x0f | TX end to XLNA On:    0x02 |
| TX end to XPA Off:    0x00 | TX end to XPA On:     0x0e |
| 62db Threshold:       0x0f | XLNA gain:            0x0d |
| XPD:                  0x01 | XPD gain:             0x05 |
| I gain:               0x0a | Tx/Rx margin:         0x0b |
| False detect backoff: 0x00 | Noise Floor Threshold: -54 |
| ADC desired size:      -32 | PGA desired size:      -80 |
|=========================================================|
| Antenna control   0:  0x00 | Antenna control   1:  0x02 |
| Antenna control   2:  0x01 | Antenna control   3:  0x00 |
| Antenna control   4:  0x00 | Antenna control   5:  0x00 |
| Antenna control   6:  0x01 | Antenna control   7:  0x02 |
| Antenna control   8:  0x00 | Antenna control   9:  0x00 |
| Antenna control  10:  0x00 | Antenna control  11:  0x00 |
|=========================================================|
| Octave Band 0:           2 | db 0:                    2 |
| Octave Band 1:           2 | db 1:                    2 |
| Octave Band 2:           2 | db 2:                    2 |
| Octave Band 3:           2 | db 3:                    2 |
\=========================================================/
/============== Per rate power calibration ===========\
| Freq | 6-24Mbit/s | 36Mbit/s |  48Mbit/s | 54Mbit/s |
|======|============|==========|===========|==========|
| 4920 |    18.00   |  16.00   |   14.00   |  12.00   |
|======|============|==========|===========|==========|
| 5040 |    18.00   |  16.00   |   14.00   |  12.00   |
|======|============|==========|===========|==========|
| 5170 |    18.00   |  16.00   |   15.00   |  13.00   |
|======|============|==========|===========|==========|
| 5240 |    19.00   |  17.00   |   15.00   |  13.00   |
|======|============|==========|===========|==========|
| 5320 |    19.00   |  17.00   |   15.00   |  13.00   |
|======|============|==========|===========|==========|
| 5500 |    19.00   |  16.00   |   14.00   |  13.00   |
|======|============|==========|===========|==========|
| 5700 |    18.00   |  16.00   |   14.00   |  13.00   |
|======|============|==========|===========|==========|
| 5825 |    17.00   |  15.00   |   13.00   |  12.00   |
|======|============|==========|===========|==========|
| 5360 |    19.01   |  19.01   |   19.01   |  19.01   |
|======|============|==========|===========|==========|
| 5720 |    19.00   |  19.00   |   19.00   |  19.00   |
\=====================================================/
/=================== Per channel power calibration ====================\
| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 |pwrx3_0|pwrx3_1|pwrx3_2|max_pwr|
|      | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 4920 |  6.75 | 16.25 | 21.00 | 22.00 |  6.00 |  6.00 | 11.25 | 22.00 |
|      |  [25] |  [50] |  [62] |  [63] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 4980 |  6.25 | 15.75 | 21.25 | 21.75 |  4.75 |  4.50 | 11.25 | 21.75 |
|      |  [25] |  [50] |  [62] |  [63] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5040 |  6.75 | 14.75 | 19.00 | 23.00 |  3.25 |  3.25 | 11.25 | 23.00 |
|      |  [25] |  [47] |  [57] |  [63] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5170 |  7.25 | 15.25 | 18.50 | 23.00 |  2.25 |  2.75 | 12.00 | 23.00 |
|      |  [25] |  [46] |  [55] |  [61] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5240 |  8.00 | 16.75 | 20.50 | 23.00 |  1.75 |  3.00 | 12.25 | 23.00 |
|      |  [25] |  [48] |  [58] |  [61] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5320 |  8.75 | 17.50 | 21.25 | 23.00 |  2.00 |  3.50 | 13.00 | 23.00 |
|      |  [25] |  [48] |  [58] |  [59] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5500 |  9.75 | 17.75 | 21.50 | 23.00 |  2.25 |  4.50 | 14.50 | 23.00 |
|      |  [25] |  [46] |  [56] |  [57] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5650 | 10.25 | 18.00 | 21.00 | 23.00 |  1.75 |  5.00 | 15.00 | 23.00 |
|      |  [25] |  [45] |  [54] |  [56] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5745 | 10.75 | 19.75 | 23.00 | 23.00 |  1.25 |  5.00 | 15.00 | 23.00 |
|      |  [25] |  [50] |  [57] |  [57] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 5825 | 10.25 | 20.00 | 22.25 | 22.25 |  0.50 |  4.75 | 14.75 | 22.25 |
|      |  [25] |  [50] |  [62] |  [63] |  [20] |  [35] |  [63] |       |
\======================================================================/

/=========================================================\
|          Calibration data for 802.11b operation         |
|=========================================================|
| I power:              0x00 | Q power:              0x00 |
| Use fixed bias:       0x00 | Max turbo power:      0x00 |
| Max XR power:         0x00 | Switch Settling Time: 0x28 |
| Tx/Rx attenuation:    0x1e | TX end to XLNA On:    0x02 |
| TX end to XPA Off:    0x00 | TX end to XPA On:     0x07 |
| 62db Threshold:       0x1c | XLNA gain:            0x0d |
| XPD:                  0x01 | XPD gain:             0x05 |
| I gain:               0x0a | Tx/Rx margin:         0x21 |
| False detect backoff: 0x00 | Noise Floor Threshold:  -1 |
| ADC desired size:      -38 | PGA desired size:      -80 |
|=========================================================|
| Antenna control   0:  0x00 | Antenna control   1:  0x02 |
| Antenna control   2:  0x11 | Antenna control   3:  0x01 |
| Antenna control   4:  0x01 | Antenna control   5:  0x01 |
| Antenna control   6:  0x01 | Antenna control   7:  0x12 |
| Antenna control   8:  0x02 | Antenna control   9:  0x02 |
| Antenna control  10:  0x02 | Antenna control  11:  0x00 |
|=========================================================|
| Octave Band 0:           2 | db 0:                    2 |
| Octave Band 1:           2 | db 1:                    2 |
| Octave Band 2:           0 | db 2:                    0 |
| Octave Band 3:           0 | db 3:                    0 |
\=========================================================/
/============== Per rate power calibration ===========\
| Freq |   1Mbit/s  | 2Mbit/s  | 5.5Mbit/s | 11Mbit/s |
|======|============|==========|===========|==========|
| 2412 |    19.01   |  19.01   |   19.01   |  19.01   |
|======|============|==========|===========|==========|
| 2484 |    19.00   |  19.00   |   19.00   |  19.00   |
\=====================================================/
/=================== Per channel power calibration ====================\
| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 |pwrx3_0|pwrx3_1|pwrx3_2|max_pwr|
|      | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 2412 |  8.00 | 15.25 | 19.50 | 23.25 |  1.50 |  3.75 | 12.00 | 23.25 |
|      |  [25] |  [46] |  [56] |  [63] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 2437 |  7.75 | 16.00 | 21.00 | 22.50 |  1.25 |  3.50 | 11.75 | 22.50 |
|      |  [25] |  [49] |  [60] |  [63] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 2472 |  7.25 | 15.75 | 21.00 | 21.75 |  0.75 |  3.25 | 11.25 | 21.75 |
|      |  [25] |  [50] |  [61] |  [63] |  [20] |  [35] |  [63] |       |
\======================================================================/

/=========================================================\
|          Calibration data for 802.11g operation         |
|=========================================================|
| I power:              0x00 | Q power:              0x17 |
| Use fixed bias:       0x01 | Max turbo power:      0x20 |
| Max XR power:         0x26 | Switch Settling Time: 0x28 |
| Tx/Rx attenuation:    0x23 | TX end to XLNA On:    0x02 |
| TX end to XPA Off:    0x00 | TX end to XPA On:     0x0e |
| 62db Threshold:       0x1c | XLNA gain:            0x0d |
| XPD:                  0x01 | XPD gain:             0x05 |
| I gain:               0x0a | Tx/Rx margin:         0x21 |
| False detect backoff: 0x00 | Noise Floor Threshold:  -1 |
| ADC desired size:      -32 | PGA desired size:      -80 |
|=========================================================|
| Antenna control   0:  0x00 | Antenna control   1:  0x02 |
| Antenna control   2:  0x11 | Antenna control   3:  0x01 |
| Antenna control   4:  0x01 | Antenna control   5:  0x01 |
| Antenna control   6:  0x01 | Antenna control   7:  0x12 |
| Antenna control   8:  0x02 | Antenna control   9:  0x02 |
| Antenna control  10:  0x02 | Antenna control  11:  0x02 |
|=========================================================|
| Octave Band 0:           2 | db 0:                    2 |
| Octave Band 1:           2 | db 1:                    2 |
| Octave Band 2:           0 | db 2:                    0 |
| Octave Band 3:           0 | db 3:                    0 |
\=========================================================/
/============== Per rate power calibration ===========\
| Freq | 6-24Mbit/s | 36Mbit/s |  48Mbit/s | 54Mbit/s |
|======|============|==========|===========|==========|
| 2412 |    19.00   |  17.01   |   16.00   |  15.01   |
|======|============|==========|===========|==========|
| 2437 |    19.00   |  18.00   |   17.00   |  16.00   |
|======|============|==========|===========|==========|
| 2472 |    19.00   |  17.01   |   16.01   |  15.00   |
\=====================================================/
/=================== Per channel power calibration ====================\
| Freq | pwr_0 | pwr_1 | pwr_2 | pwr_3 |pwrx3_0|pwrx3_1|pwrx3_2|max_pwr|
|      | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac | pcdac |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 2412 |  7.25 | 16.00 | 21.75 | 22.50 |  0.25 |  3.75 | 11.50 | 22.50 |
|      |  [25] |  [50] |  [62] |  [63] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 2437 |  7.00 | 16.25 | 20.75 | 21.75 |  0.00 |  3.50 | 11.25 | 21.75 |
|      |  [25] |  [50] |  [61] |  [63] |  [20] |  [35] |  [63] |       |
|======|=======|=======|=======|=======|=======|=======|=======|=======|
| 2472 |  6.50 | 15.50 | 20.75 | 21.00 |  0.00 |  3.00 | 10.50 | 21.00 |
|      |  [25] |  [50] |  [62] |  [63] |  [20] |  [35] |  [63] |       |
\======================================================================/

GPIO registers: CR 0x00000000, DO 0x00000000, DI 0x00000001

EEPROM dump (2048 bytes)
==============================================
0000:  0013 168c 0200 0001 0000 5001 0000 1012
0008:  185f 1c0a 0100 0000 01c2 0002 c606 0001
0010:  0000 0000 0000 0000 0000 0000 0000 0000
0018:  0000 0000 0000 0000 0000 3445 1223 0001
0020:  0000 0000 0000 0000 0000 0000 0000 0000
0028:  0000 0000 0000 0000 0000 0000 0000 0000
0030:  0000 0000 0000 0000 0000 0000 0000 0000
0038:  0000 0000 0000 0000 0000 5aa5 0000 0000
0040:  0313 4943 2053 7104 1202 0400 0306 0001
0048:  0000 0500 410e 39b1 1eb5 4e2d 3056 ffff
0050:  e902 0700 0106 0000 0100 1500 0752 4101
0058:  6874 7265 736f 4320 6d6f 756d 696e 6163
0060:  6974 6e6f 2c73 4920 636e 002e 5241 3035
0068:  3130 302d 3030 2d30 3030 3030 5700 7269
0070:  6c65 7365 2073 414c 204e 6552 6566 6572
0078:  636e 2065 6143 6472 3000 0030 00ff 2100
0080:  0602 2201 0205 8d80 005b 0522 4002 8954
0088:  2200 0205 1b00 00b7 0522 8002 12a8 2201
0090:  0205 3600 016e 0522 0002 2551 2202 0205
0098:  6c00 02dc 0522 8002 37f9 2203 0205 a200
00a0:  044a 0222 0803 0822 0604 0100 2312 4534
00a8:  0222 0105 00ff 0000 0000 0000 0000 0000
00b0:  ffff ffff ffff ffff ffff ffff ffff ffff
00b8:  ffff ffff ffff ffff ffff ffff 0000 0000
00c0:  ee2b 4008 5a07 0101 420f 41a5 0101 3002
00c8:  0003 0000 0000 0000 0000 0000 0000 0000
00d0:  0000 0000 0000 0000 2d3c 0081 0000 0108
00d8:  0000 e049 2492 020f 000e b0ca 21ab 4024
00e0:  0af1 000b 0000 0000 0000 0000 0000 0000
00e8:  0000 0000 0000 0000 0000 0000 0000 0000
00f0:  0000 0000 2878 0091 0410 4148 2082 da22
00f8:  021c 0007 b0ff 01ab 4012 0001 8970 21ac
0100:  0000 0000 0000 0000 0000 0000 0000 0000
0108:  0000 0000 0000 0000 0000 288c 0091 0410
0110:  4148 2082 e022 021c 000e b0ff 21ab 4012
0118:  7851 8970 1320 21ac 00bb 0003 0000 0000
0120:  0000 0000 0000 0000 0000 0000 0000 0000
0128:  1013 1112 1440 3031 3234 0000 0000 0000
0130:  0000 0000 0000 0000 0000 0000 0000 0000
0138:  0000 0000 0000 0000 0000 0000 0000 0000
0140:  0000 0000 0000 0000 0000 0000 0000 0000
0148:  0000 0000 0000 0000 0000 0000 0000 0000
0150:  2418 4a30 6858 aa8c cdbd 411b 5854 0599
0158:  1818 192d 3f19 5755 0599 1213 192d 3b1b
0160:  5c4c 1956 0d0d 192d 3d1d 5c4a 1935 0b09
0168:  1930 4320 5c52 0d57 0c07 1931 4623 5c55
0170:  0557 0e08 1934 4727 5c56 0555 1209 193a
0178:  4829 5c54 0934 1407 193c 4f2b 5c5c 00f9
0180:  1405 193c 5029 5959 0599 1302 193b 3d20
0188:  5d4e 1d55 0f06 1930 401f 5a54 0d78 0e05
0190:  192f 3f1d 5754 0979 0d03 192d 401d 5a57
0198:  0599 0f01 192e 411c 5753 0979 0e00 192d
01a0:  3e1a 5453 0599 0c00 192a 1892 0718 3092
01a8:  0718 4a92 079a 589a 279a 689a 279a 8c9a
01b0:  071a b492 071a cd89 e698 709e 79e7 b89a
01b8:  69a6 709a 381f 899a 48a0 ac9a 385e 4c58
01c0:  5c68 bdc1 cd00 2222 2423 2464 2400 5052
01c8:  5a60 62c0 c1c9 2262 2224 2423 6323 7075
01d0:  a200 0000 0000 2868 2800 0000 0000 7075
01d8:  9da2 0000 0000 2166 6621 0000 0000 8989
01e0:  0000 0000 0000 2626 0000 0000 0000 4a56
01e8:  0000 0000 0000 3c3c 0000 0000 0000 4c68
01f0:  8cb4 bdc1 cd00 2424 2424 3c7c 3c00 7075
01f8:  ac00 0000 0000 2060 2000 0000 0000 7075
0200:  ac00 0000 0000 1d5d 1d00 0000 0000 8989
0208:  0000 0000 0000 1e1e 0000 0000 0000 ea0e
0210:  c000 0e07 8042 a204 0002 0e03 8186 9858
0218:  0000 0e01 800c 9824 0707 0e02 8063 9860
0220:  0003 03ff a210 0080 6333 03ff a214 0010
0228:  6c10 03ff a21c 1883 800a 03ff a220 0188
0230:  30c6 05ff c0fd 1001 c8f5 707f c8fc 1000
0238:  c85a 2001 c85c 2002 c85e 2001 c8fe 1001
0240:  c519 1001 cc01 2001 cc03 2001 cc8b 1001
0248:  cc8c 1001 dc92 1001 0fff 8081 1230 0001
0250:  0fff 8010 982c a002 09ff 8063 0000 0000
0258:  0000 0000 0000 0000 0000 0000 0000 0000
0260:  0000 0000 0000 0000 0000 0000 0000 0000
0268:  0000 0000 0000 0000 0000 0000 0000 0000
0270:  0000 0000 0000 0000 0000 0000 0000 0000
0278:  0000 0000 0000 0000 0000 0000 0000 0000
0280:  0000 0000 0000 0000 0000 0000 0000 0000
0288:  0000 0000 0000 0000 0000 0000 0000 0000
0290:  0000 0000 0000 0000 0000 0000 0000 0000
0298:  0000 0000 0000 0000 0000 0000 0000 0000
02a0:  0000 0000 0000 0000 0000 0000 0000 0000
02a8:  0000 0000 0000 0000 0000 0000 0000 0000
02b0:  0000 0000 0000 0000 0000 0000 0000 0000
02b8:  0000 0000 0000 0000 0000 0000 0000 0000
02c0:  0000 0000 0000 0000 0000 0000 0000 0000
02c8:  0000 0000 0000 0000 0000 0000 0000 0000
02d0:  0000 0000 0000 0000 0000 0000 0000 0000
02d8:  0000 0000 0000 0000 0000 0000 0000 0000
02e0:  0000 0000 0000 0000 0000 0000 0000 0000
02e8:  0000 0000 0000 0000 0000 0000 0000 0000
02f0:  0000 0000 0000 0000 0000 0000 0000 0000
02f8:  0000 0000 0000 0000 0000 0000 0000 0000
0300:  0000 0000 0000 0000 0000 0000 0000 0000
0308:  0000 0000 0000 0000 0000 0000 0000 0000
0310:  0000 0000 0000 0000 0000 0000 0000 0000
0318:  0000 0000 0000 0000 0000 0000 0000 0000
0320:  0000 0000 0000 0000 0000 0000 0000 0000
0328:  0000 0000 0000 0000 0000 0000 0000 0000
0330:  0000 0000 0000 0000 0000 0000 0000 0000
0338:  0000 0000 0000 0000 0000 0000 0000 0000
0340:  0000 0000 0000 0000 0000 0000 0000 0000
0348:  0000 0000 0000 0000 0000 0000 0000 0000
0350:  0000 0000 0000 0000 0000 0000 0000 0000
0358:  0000 0000 0000 0000 0000 0000 0000 0000
0360:  0000 0000 0000 0000 0000 0000 0000 0000
0368:  0000 0000 0000 0000 0000 0000 0000 0000
0370:  0000 0000 0000 0000 0000 0000 0000 0000
0378:  0000 0000 0000 0000 0000 0000 0000 0000
0380:  0000 0000 0000 0000 0000 0000 0000 0000
0388:  0000 0000 0000 0000 0000 0000 0000 0000
0390:  0000 0000 0000 0000 0000 0000 0000 0000
0398:  0000 0000 0000 0000 0000 0000 0000 0000
03a0:  0000 0000 0000 0000 0000 0000 0000 0000
03a8:  0000 0000 0000 0000 0000 0000 0000 0000
03b0:  0000 0000 0000 0000 0000 0000 0000 0000
03b8:  0000 0000 0000 0000 0000 0000 0000 0000
03c0:  0000 0000 0000 0000 0000 0000 0000 0000
03c8:  0000 0000 0000 0000 0000 0000 0000 0000
03d0:  0000 0000 0000 0000 0000 0000 0000 0000
03d8:  0000 0000 0000 0000 0000 0000 0000 0000
03e0:  0000 0000 0000 0000 0000 0000 0000 0000
03e8:  0000 0000 0000 0000 0000 0000 0000 0000
03f0:  0000 0000 0000 0000 0000 0000 0000 0000
03f8:  0000 0000 0000 0000 0000 0000 0000 0000
==============================================
STA_ID0: 00:00:00:00:00:00
STA_ID1: 0x10000000, AP: 0, IBSS: 0, KeyCache Disable: 0
TIMER0: 0x0000fdee, TBTT: 65006, TU: 0xc749fdee
TIMER1: 0x0007ffff, DMAb: 65535, TU: 0xc749ffff (+529)
TIMER2: 0x015bcffd, SWBA: 31231, TU: 0xc76b79ff (+2194449)
TIMER3: 0x0000fddf, ATIM: 64991, TU: 0xc749fddf (-15)
TSF: 0xcad0ef1d26f6ab81, TSFTU: 48554, TU: 0xc749bdaa
BEACON: 0x007bfbe7
LAST_TSTP: 0xfbe5fbef

-- 
Krzysztof Halasa

^ permalink raw reply

* Re: [PATCH 1/3] iwmc3200top: Add Intel Wireless MultiCom 3200 top driver.
From: Marcel Holtmann @ 2009-10-10 11:01 UTC (permalink / raw)
  To: Tomas Winkler
  Cc: davem, linville, netdev, linux-wireless, linux-mmc, yi.zhu,
	inaky.perez-gonzalez, cindy.h.kao, guy.cohen, ron.rindjunsky
In-Reply-To: <1253662724-16497-2-git-send-email-tomas.winkler@intel.com>

Hi Tomas,

> This patch adds Intel Wireless MultiCom 3200 top driver.
> IWMC3200 is 4Wireless Com CHIP (GPS/BT/WiFi/WiMAX).
> Top driver is responsible for device initialization and firmware download.
> Firmware handled by top is responsible for top itself and
> as well as bluetooth and GPS coms. (Wifi and WiMax provide their own
> firmware)
> In addition top driver is used to retrieve firmware logs
> and supports other debugging features
> 
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> ---
>  drivers/misc/Kconfig                   |    1 +
>  drivers/misc/Makefile                  |    1 +
>  drivers/misc/iwmc3200top/Kconfig       |   20 +
>  drivers/misc/iwmc3200top/Makefile      |   29 ++
>  drivers/misc/iwmc3200top/debugfs.c     |  145 +++++++
>  drivers/misc/iwmc3200top/debugfs.h     |   61 +++
>  drivers/misc/iwmc3200top/fw-download.c |  359 ++++++++++++++++
>  drivers/misc/iwmc3200top/fw-msg.h      |  113 +++++
>  drivers/misc/iwmc3200top/iwmc3200top.h |  202 +++++++++
>  drivers/misc/iwmc3200top/log.c         |  339 +++++++++++++++
>  drivers/misc/iwmc3200top/log.h         |  158 +++++++
>  drivers/misc/iwmc3200top/main.c        |  702 ++++++++++++++++++++++++++++++++
>  12 files changed, 2130 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/misc/iwmc3200top/Kconfig
>  create mode 100644 drivers/misc/iwmc3200top/Makefile
>  create mode 100644 drivers/misc/iwmc3200top/debugfs.c
>  create mode 100644 drivers/misc/iwmc3200top/debugfs.h
>  create mode 100644 drivers/misc/iwmc3200top/fw-download.c
>  create mode 100644 drivers/misc/iwmc3200top/fw-msg.h
>  create mode 100644 drivers/misc/iwmc3200top/iwmc3200top.h
>  create mode 100644 drivers/misc/iwmc3200top/log.c
>  create mode 100644 drivers/misc/iwmc3200top/log.h
>  create mode 100644 drivers/misc/iwmc3200top/main.c
> 
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 68ab39d..6f85b43 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -236,5 +236,6 @@ config ISL29003
>  source "drivers/misc/c2port/Kconfig"
>  source "drivers/misc/eeprom/Kconfig"
>  source "drivers/misc/cb710/Kconfig"
> +source "drivers/misc/iwmc3200top/Kconfig"
>  
>  endif # MISC_DEVICES
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 36f733c..97f5303 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -20,5 +20,6 @@ obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
>  obj-$(CONFIG_HP_ILO)		+= hpilo.o
>  obj-$(CONFIG_ISL29003)		+= isl29003.o
>  obj-$(CONFIG_C2PORT)		+= c2port/
> +obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
>  obj-y				+= eeprom/
>  obj-y				+= cb710/
> diff --git a/drivers/misc/iwmc3200top/Kconfig b/drivers/misc/iwmc3200top/Kconfig
> new file mode 100644
> index 0000000..9e4b88f
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/Kconfig
> @@ -0,0 +1,20 @@
> +config IWMC3200TOP
> +        tristate "Intel Wireless MultiCom Top Driver"
> +        depends on MMC && EXPERIMENTAL
> +        select FW_LOADER
> +	---help---
> +	  Intel Wireless MultiCom 3200 Top driver is responsible for
> +	  for firmware load and enabled coms enumeration
> +
> +config IWMC3200TOP_DEBUG
> +	bool "Enable full debug output of iwmc3200top Driver"
> +	depends on IWMC3200TOP
> +	---help---
> +	  Enable full debug output of iwmc3200top Driver
> +
> +config IWMC3200TOP_DEBUGFS
> +	bool "Enable Debugfs debugging interface for iwmc3200top"
> +	depends on IWMC3200TOP
> +	---help---
> +	  Enable creation of debugfs files for iwmc3200top
> +
> diff --git a/drivers/misc/iwmc3200top/Makefile b/drivers/misc/iwmc3200top/Makefile
> new file mode 100644
> index 0000000..fbf53fb
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/Makefile
> @@ -0,0 +1,29 @@
> +# iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> +# drivers/misc/iwmc3200top/Makefile
> +#
> +# Copyright (C) 2009 Intel Corporation. All rights reserved.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License version
> +# 2 as published by the Free Software Foundation.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> +# 02110-1301, USA.
> +#
> +#
> +# Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> +#  -
> +#
> +#
> +
> +obj-$(CONFIG_IWMC3200TOP)	+= iwmc3200top.o
> +iwmc3200top-objs	:= main.o fw-download.o
> +iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUG) += log.o
> +iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUGFS) += debugfs.o
> diff --git a/drivers/misc/iwmc3200top/debugfs.c b/drivers/misc/iwmc3200top/debugfs.c
> new file mode 100644
> index 0000000..a531f6c
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/debugfs.c
> @@ -0,0 +1,145 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/debufs.c
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/string.h>
> +#include <linux/ctype.h>
> +#include <linux/mmc/sdio_func.h>
> +#include <linux/mmc/sdio.h>
> +
> +#include "iwmc3200top.h"
> +#include "log.h"
> +#include "fw-msg.h"
> +#include "debugfs.h"
> +
> +/*      Constants definition        */
> +#define HEXADECIMAL_RADIX	16
> +
> +/*      Functions definition        */
> +
> +
> +/*      Debugfs macros       */
> +#define DEBUGFS_ADD_DIR(name, parent) do {			\
> +	dbgfs->dir_##name = debugfs_create_dir(#name, parent);	\
> +	if (!(dbgfs->dir_##name))				\
> +		goto err;					\
> +} while (0)
> +
> +#define DEBUGFS_ADD_FILE(name, parent) do {				\
> +	dbgfs->dbgfs_##parent##_files.file_##name =                     \
> +	debugfs_create_file(#name, 0644, dbgfs->dir_##parent, priv,     \
> +				&iwmct_dbgfs_##name##_ops);               \
> +	if (!(dbgfs->dbgfs_##parent##_files.file_##name))		\
> +		goto err;						\
> +} while (0)
> +
> +#define DEBUGFS_REMOVE(name)  do {	\
> +	debugfs_remove(name);		\
> +	name = NULL;			\
> +} while (0)
> +
> +#define DEBUGFS_READ_FUNC(name)						\
> +ssize_t iwmct_dbgfs_##name##_read(struct file *file,			\
> +				  char __user *user_buf,		\
> +				  size_t count, loff_t *ppos);
> +
> +#define DEBUGFS_WRITE_FUNC(name)					\
> +ssize_t iwmct_dbgfs_##name##_write(struct file *file,			\
> +				   const char __user *user_buf,		\
> +				   size_t count, loff_t *ppos);
> +
> +#define DEBUGFS_READ_FILE_OPS(name)					\
> +	DEBUGFS_READ_FUNC(name)						\
> +	static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
> +		.read = iwmct_dbgfs_##name##_read,			\
> +		.open = iwmct_dbgfs_open_file_generic,			\
> +	};
> +
> +#define DEBUGFS_WRITE_FILE_OPS(name)					\
> +	DEBUGFS_WRITE_FUNC(name)					\
> +	static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
> +		.write = iwmct_dbgfs_##name##_write,			\
> +		.open = iwmct_dbgfs_open_file_generic,			\
> +	};
> +
> +#define DEBUGFS_READ_WRITE_FILE_OPS(name)				\
> +	DEBUGFS_READ_FUNC(name)						\
> +	DEBUGFS_WRITE_FUNC(name)					\
> +	static const struct file_operations iwmct_dbgfs_##name##_ops = {\
> +		.write = iwmct_dbgfs_##name##_write,			\
> +		.read = iwmct_dbgfs_##name##_read,			\
> +		.open = iwmct_dbgfs_open_file_generic,			\
> +	};
> +
> +
> +/*      Debugfs file ops definitions        */
> +
> +/*      Debugfs registration functions        */
> +
> +/*
> + * Create the debugfs files and directories
> + *
> + */

so for me the whole debug infrastructure is way too much overhead for
what this driver has to achieve. What is the benefit of having all these
debugfs support. What is it trying to achieve?

Also all these macros really obfuscate the code for no real benefit. If
you wanna keep debugfs support, then just use the functions directly.
They are not that complicated that an extra abstraction layer is needed.

> +void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
> +{
> +	struct iwmct_debugfs *dbgfs;
> +
> +	dbgfs = kzalloc(sizeof(struct iwmct_debugfs), GFP_KERNEL);
> +	if (!dbgfs) {
> +		LOG_ERROR(priv, DEBUGFS, "failed to allocate %zd bytes\n",
> +					sizeof(struct iwmct_debugfs));
> +		goto err;
> +	}
> +
> +	priv->dbgfs = dbgfs;
> +	dbgfs->name = name;
> +	dbgfs->dir_drv = debugfs_create_dir(name, NULL);
> +	if (!dbgfs->dir_drv) {
> +		LOG_ERROR(priv, DEBUGFS, "failed to create debugfs dir\n");
> +		goto err;
> +	}
> +
> +
> +err:
> +	return;
> +}

goto err. Seriously. Just call return in the error case. And also there
is a memory leak if the debugfs_create_dir fails.

> +/**
> + * Remove the debugfs files and directories
> + *
> + */
> +void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
> +{
> +	if (!dbgfs)
> +		return;
> +
> +
> +	DEBUGFS_REMOVE(dbgfs->dir_drv);
> +	kfree(dbgfs);
> +
> +	dbgfs = NULL;
> +}
> +
> diff --git a/drivers/misc/iwmc3200top/debugfs.h b/drivers/misc/iwmc3200top/debugfs.h
> new file mode 100644
> index 0000000..24b1369
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/debugfs.h
> @@ -0,0 +1,61 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/debufs.h
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#ifndef __DEBUGFS_H__
> +#define __DEBUGFS_H__
> +
> +
> +#ifdef CONFIG_IWMC3200TOP_DEBUGFS
> +
> +#include <linux/debugfs.h>
> +
> +struct iwmct_debugfs {
> +	const char *name;
> +	struct dentry *dir_drv;
> +	struct dir_drv_files {
> +	} dbgfs_drv_files;
> +};
> +
> +void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name);
> +void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs);
> +
> +#else /* CONFIG_IWMC3200TOP_DEBUGFS */
> +
> +/* struct iwmct_debugfs is empty if CONFIG_IWMC3200TOP_DEBUGFS is not defined */
> +struct iwmct_debugfs {
> +};

If struct iwmct_debugfs is never referenced directly then a simple
forward struct imwct_debugfs; declaration is good enough.

> +
> +static inline void
> +iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
> +{}
> +
> +static inline void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
> +{}
> +
> +#endif /* CONFIG_IWMC3200TOP_DEBUGFS */
> +
> +#endif /* __DEBUGFS_H__ */
> +
> diff --git a/drivers/misc/iwmc3200top/fw-download.c b/drivers/misc/iwmc3200top/fw-download.c
> new file mode 100644
> index 0000000..33cb693
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/fw-download.c
> @@ -0,0 +1,359 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/fw-download.c
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/mmc/sdio_func.h>
> +#include <asm/unaligned.h>
> +
> +#include "iwmc3200top.h"
> +#include "log.h"
> +#include "fw-msg.h"
> +
> +#define CHECKSUM_BYTES_NUM sizeof(u32)
> +
> +/**
> +  init parser struct with file
> + */
> +static int iwmct_fw_parser_init(struct iwmct_priv *priv, const u8 *file,
> +			      size_t file_size, size_t block_size)
> +{
> +	struct iwmct_parser *parser = &priv->parser;
> +	struct iwmct_fw_hdr *fw_hdr = &parser->versions;
> +
> +	LOG_INFOEX(priv, INIT, "-->\n");
> +
> +	LOG_INFO(priv, FW_DOWNLOAD, "file_size=%zd\n", file_size);

This logging is overkill. Can we just hide this via pr_debug and then
use just simply dynamic_printk support.

> +
> +	parser->file = file;
> +	parser->file_size = file_size;
> +	parser->cur_pos = 0;
> +	parser->buf = NULL;
> +
> +	parser->buf = kzalloc(block_size, GFP_KERNEL);
> +	if (!parser->buf) {
> +		LOG_ERROR(priv, FW_DOWNLOAD, "kzalloc error\n");
> +		return -ENOMEM;
> +	}
> +	parser->buf_size = block_size;
> +
> +	/* extract fw versions */
> +	memcpy(fw_hdr, parser->file, sizeof(struct iwmct_fw_hdr));
> +	LOG_INFO(priv, FW_DOWNLOAD, "fw versions are:\n"
> +		"top %u.%u.%u gps %u.%u.%u bt %u.%u.%u tic %s\n",
> +		fw_hdr->top_major, fw_hdr->top_minor, fw_hdr->top_revision,
> +		fw_hdr->gps_major, fw_hdr->gps_minor, fw_hdr->gps_revision,
> +		fw_hdr->bt_major, fw_hdr->bt_minor, fw_hdr->bt_revision,
> +		fw_hdr->tic_name);
> +
> +	parser->cur_pos += sizeof(struct iwmct_fw_hdr);
> +
> +	LOG_INFOEX(priv, INIT, "<--\n");
> +	return 0;
> +}
> +
> +static bool iwmct_checksum(struct iwmct_priv *priv)
> +{
> +	struct iwmct_parser *parser = &priv->parser;
> +	__le32 *file = (__le32 *)parser->file;
> +	int i, pad, steps;
> +	u32 accum = 0;
> +	u32 checksum;
> +	u32 mask = 0xffffffff;
> +
> +	pad = (parser->file_size - CHECKSUM_BYTES_NUM) % 4;
> +	steps =  (parser->file_size - CHECKSUM_BYTES_NUM) / 4;
> +
> +	LOG_INFO(priv, FW_DOWNLOAD, "pad=%d steps=%d\n", pad, steps);
> +
> +	for (i = 0; i < steps; i++)
> +		accum += le32_to_cpu(file[i]);
> +
> +	if (pad) {
> +		mask <<= 8 * (4 - pad);
> +		accum += le32_to_cpu(file[steps]) & mask;
> +	}
> +
> +	checksum = get_unaligned_le32((__le32 *)(parser->file +
> +			parser->file_size - CHECKSUM_BYTES_NUM));

The access to file and parser->file. One with unaligned access and the
other with, looks wrong. And it looks way to complicated.

Can we just not have a proper __le32 type of parser->file to begin with.

> +
> +	LOG_INFO(priv, FW_DOWNLOAD,
> +		"compare checksum accum=0x%x to checksum=0x%x\n",
> +		accum, checksum);
> +
> +	return checksum == accum;
> +}
> +
> +static int iwmct_parse_next_section(struct iwmct_priv *priv, const u8 **p_sec,
> +				  size_t *sec_size, __le32 *sec_addr)
> +{
> +	struct iwmct_parser *parser = &priv->parser;
> +	struct iwmct_dbg *dbg = &priv->dbg;
> +	struct iwmct_fw_sec_hdr *sec_hdr;
> +
> +	LOG_INFOEX(priv, INIT, "-->\n");
> +
> +	while (parser->cur_pos + sizeof(struct iwmct_fw_sec_hdr)
> +		<= parser->file_size) {
> +
> +		sec_hdr = (struct iwmct_fw_sec_hdr *)
> +				(parser->file + parser->cur_pos);
> +		parser->cur_pos += sizeof(struct iwmct_fw_sec_hdr);
> +
> +		LOG_INFO(priv, FW_DOWNLOAD,
> +			"sec hdr: type=%s addr=0x%x size=%d\n",
> +			sec_hdr->type, sec_hdr->target_addr,
> +			sec_hdr->data_size);
> +
> +		if (strcmp(sec_hdr->type, "ENT") == 0)
> +			parser->entry_point = le32_to_cpu(sec_hdr->target_addr);
> +		else if (strcmp(sec_hdr->type, "LBL") == 0)
> +			strcpy(dbg->label_fw, parser->file + parser->cur_pos);
> +		else if (((strcmp(sec_hdr->type, "TOP") == 0) &&
> +			  (priv->barker & BARKER_DNLOAD_TOP_MSK)) ||
> +			 ((strcmp(sec_hdr->type, "GPS") == 0) &&
> +			  (priv->barker & BARKER_DNLOAD_GPS_MSK)) ||
> +			 ((strcmp(sec_hdr->type, "BTH") == 0) &&
> +			  (priv->barker & BARKER_DNLOAD_BT_MSK))) {
> +			*sec_addr = sec_hdr->target_addr;
> +			*sec_size = le32_to_cpu(sec_hdr->data_size);
> +			*p_sec = parser->file + parser->cur_pos;
> +			parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
> +			return 1;

This if statement is unreadable. This indentation gives me a headache.

Also this function better return bool and not int.

> +		} else if (strcmp(sec_hdr->type, "LOG") != 0)
> +			LOG_WARNING(priv, FW_DOWNLOAD,
> +				    "skipping section type %s\n",
> +				    sec_hdr->type);
> +
> +		parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
> +		LOG_INFO(priv, FW_DOWNLOAD,
> +			"finished with section cur_pos=%zd\n", parser->cur_pos);
> +	}
> +
> +	LOG_INFOEX(priv, INIT, "<--\n");
> +	return 0;
> +}
> +
> +static int iwmct_download_section(struct iwmct_priv *priv, const u8 *p_sec,
> +				size_t sec_size, __le32 addr)
> +{
> +	struct iwmct_parser *parser = &priv->parser;
> +	struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
> +	const u8 *cur_block = p_sec;
> +	size_t sent = 0;
> +	int cnt = 0;
> +	int ret = 0;
> +	u32 cmd = 0;
> +
> +	LOG_INFOEX(priv, INIT, "-->\n");
> +	LOG_INFO(priv, FW_DOWNLOAD, "Download address 0x%x size 0x%zx\n",
> +				addr, sec_size);
> +
> +	while (sent < sec_size) {
> +		int i;
> +		u32 chksm = 0;
> +		u32 reset = atomic_read(&priv->reset);
> +		/* actual FW data */
> +		u32 data_size = min(parser->buf_size - sizeof(*hdr),
> +				    sec_size - sent);
> +		/* Pad to block size */
> +		u32 trans_size = (data_size + sizeof(*hdr) +
> +				  IWMC_SDIO_BLK_SIZE - 1) &
> +				  ~(IWMC_SDIO_BLK_SIZE - 1);
> +		++cnt;
> +
> +		/* in case of reset, interrupt FW DOWNLAOD */
> +		if (reset) {
> +			LOG_INFO(priv, FW_DOWNLOAD,
> +				 "Reset detected. Abort FW download!!!");
> +			ret = -ECANCELED;
> +			goto exit;
> +		}
> +
> +		memset(parser->buf, 0, parser->buf_size);
> +		cmd |= IWMC_OPCODE_WRITE << CMD_HDR_OPCODE_POS;
> +		cmd |= IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
> +		cmd |= (priv->dbg.direct ? 1 : 0) << CMD_HDR_DIRECT_ACCESS_POS;
> +		cmd |= (priv->dbg.checksum ? 1 : 0) << CMD_HDR_USE_CHECKSUM_POS;
> +		hdr->data_size = cpu_to_le32(data_size);
> +		hdr->target_addr = addr;
> +
> +		/* checksum is allowed for sizes divisible by 4 */
> +		if (data_size & 0x3)
> +			cmd &= ~CMD_HDR_USE_CHECKSUM_MSK;
> +
> +		memcpy(hdr->data, cur_block, data_size);
> +
> +
> +		if (cmd & CMD_HDR_USE_CHECKSUM_MSK) {
> +
> +			chksm = data_size + le32_to_cpu(addr) + cmd;
> +			for (i = 0; i < data_size >> 2; i++)
> +				chksm += ((u32 *)cur_block)[i];
> +
> +			hdr->block_chksm = cpu_to_le32(chksm);
> +			LOG_INFO(priv, FW_DOWNLOAD, "Checksum = 0x%X\n",
> +				 hdr->block_chksm);
> +		}
> +
> +		LOG_INFO(priv, FW_DOWNLOAD, "trans#%d, len=%d, sent=%zd, "
> +				"sec_size=%zd, startAddress 0x%X\n",
> +				cnt, trans_size, sent, sec_size, addr);
> +
> +		if (priv->dbg.dump)
> +			LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, trans_size);
> +
> +
> +		hdr->cmd = cpu_to_le32(cmd);
> +		/* send it down */
> +		/* TODO: add more proper sending and error checking */
> +		ret = iwmct_tx(priv, 0, parser->buf, trans_size);
> +		if (ret != 0) {
> +			LOG_INFO(priv, FW_DOWNLOAD,
> +				"iwmct_tx returned %d\n", ret);
> +			goto exit;
> +		}
> +
> +		addr = cpu_to_le32(le32_to_cpu(addr) + data_size);
> +		sent += data_size;
> +		cur_block = p_sec + sent;
> +
> +		if (priv->dbg.blocks && (cnt + 1) >= priv->dbg.blocks) {
> +			LOG_INFO(priv, FW_DOWNLOAD,
> +				"Block number limit is reached [%d]\n",
> +				priv->dbg.blocks);
> +			break;
> +		}
> +	}
> +
> +	if (sent < sec_size)
> +		ret = -EINVAL;
> +exit:
> +	LOG_INFOEX(priv, INIT, "<--\n");
> +	return ret;
> +}
> +
> +static int iwmct_kick_fw(struct iwmct_priv *priv, bool jump)
> +{
> +	struct iwmct_parser *parser = &priv->parser;
> +	struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
> +	int ret;
> +	u32 cmd;
> +
> +	LOG_INFOEX(priv, INIT, "-->\n");
> +
> +	memset(parser->buf, 0, parser->buf_size);
> +	cmd = IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
> +	if (jump) {
> +		cmd |= IWMC_OPCODE_JUMP << CMD_HDR_OPCODE_POS;
> +		hdr->target_addr = cpu_to_le32(parser->entry_point);
> +		LOG_INFO(priv, FW_DOWNLOAD, "jump address 0x%x\n",
> +				parser->entry_point);
> +	} else {
> +		cmd |= IWMC_OPCODE_LAST_COMMAND << CMD_HDR_OPCODE_POS;
> +		LOG_INFO(priv, FW_DOWNLOAD, "last command\n");
> +	}
> +
> +	hdr->cmd = cpu_to_le32(cmd);
> +
> +	LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, sizeof(*hdr));
> +	/* send it down */
> +	/* TODO: add more proper sending and error checking */
> +	ret = iwmct_tx(priv, 0, parser->buf, IWMC_SDIO_BLK_SIZE);
> +	if (ret)
> +		LOG_INFO(priv, FW_DOWNLOAD, "iwmct_tx returned %d", ret);
> +
> +	LOG_INFOEX(priv, INIT, "<--\n");
> +	return 0;
> +}
> +
> +int iwmct_fw_load(struct iwmct_priv *priv)
> +{
> +	const struct firmware *raw = NULL;
> +	__le32 addr;
> +	size_t len;
> +	const u8 *pdata;
> +	const u8 *name = "iwmc3200top.1.fw";
> +	int ret = 0;
> +
> +	/* clear parser struct */
> +	memset(&priv->parser, 0, sizeof(struct iwmct_parser));
> +	if (!name) {
> +		ret = -EINVAL;
> +		goto exit;
> +	}
> +
> +	/* get the firmware */
> +	ret = request_firmware(&raw, name, &priv->func->dev);
> +	if (ret < 0) {
> +		LOG_ERROR(priv, FW_DOWNLOAD, "%s request_firmware failed %d\n",
> +			  name, ret);
> +		goto exit;
> +	}
> +
> +	if (raw->size < sizeof(struct iwmct_fw_sec_hdr)) {
> +		LOG_ERROR(priv, FW_DOWNLOAD, "%s smaller then (%zd) (%zd)\n",
> +			  name, sizeof(struct iwmct_fw_sec_hdr), raw->size);
> +		goto exit;
> +	}
> +
> +	LOG_INFO(priv, FW_DOWNLOAD, "Read firmware '%s'\n", name);
> +
> +	ret = iwmct_fw_parser_init(priv, raw->data, raw->size, priv->trans_len);
> +	if (ret < 0) {
> +		LOG_ERROR(priv, FW_DOWNLOAD,
> +			  "iwmct_parser_init failed: Reason %d\n", ret);
> +		goto exit;
> +	}
> +
> +	/* checksum  */
> +	if (!iwmct_checksum(priv)) {
> +		LOG_ERROR(priv, FW_DOWNLOAD, "checksum error\n");
> +		ret = -EINVAL;
> +		goto exit;
> +	}
> +
> +	/* download firmware to device */
> +	while (iwmct_parse_next_section(priv, &pdata, &len, &addr)) {
> +		if (iwmct_download_section(priv, pdata, len, addr)) {
> +			LOG_ERROR(priv, FW_DOWNLOAD,
> +				  "%s download section failed\n", name);
> +			ret = -EIO;
> +			goto exit;
> +		}
> +	}
> +
> +	iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));
> +
> +exit:
> +	kfree(priv->parser.buf);
> +
> +	if (raw)
> +		release_firmware(raw);
> +
> +	raw = NULL;
> +
> +	return ret;
> +}
> diff --git a/drivers/misc/iwmc3200top/fw-msg.h b/drivers/misc/iwmc3200top/fw-msg.h
> new file mode 100644
> index 0000000..9e26b75
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/fw-msg.h
> @@ -0,0 +1,113 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/fw-msg.h
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#ifndef __FWMSG_H__
> +#define __FWMSG_H__
> +
> +#define COMM_TYPE_D2H           	0xFF
> +#define COMM_TYPE_H2D           	0xEE
> +
> +#define COMM_CATEGORY_OPERATIONAL      	0x00
> +#define COMM_CATEGORY_DEBUG            	0x01
> +#define COMM_CATEGORY_TESTABILITY      	0x02
> +#define COMM_CATEGORY_DIAGNOSTICS      	0x03
> +
> +#define OP_DBG_ZSTR_MSG			cpu_to_le16(0x1A)
> +
> +#define FW_LOG_SRC_MAX			32
> +#define FW_LOG_SRC_ALL			255
> +
> +#define FW_STRING_TABLE_ADDR		cpu_to_le32(0x0C000000)
> +
> +#define CMD_DBG_LOG_LEVEL		cpu_to_le16(0x0001)
> +#define CMD_TST_DEV_RESET		cpu_to_le16(0x0060)
> +#define CMD_TST_FUNC_RESET		cpu_to_le16(0x0062)
> +#define CMD_TST_IFACE_RESET		cpu_to_le16(0x0064)
> +#define CMD_TST_CPU_UTILIZATION		cpu_to_le16(0x0065)
> +#define CMD_TST_TOP_DEEP_SLEEP		cpu_to_le16(0x0080)
> +#define CMD_TST_WAKEUP			cpu_to_le16(0x0081)
> +#define CMD_TST_FUNC_WAKEUP		cpu_to_le16(0x0082)
> +#define CMD_TST_FUNC_DEEP_SLEEP_REQUEST	cpu_to_le16(0x0083)
> +#define CMD_TST_GET_MEM_DUMP		cpu_to_le16(0x0096)
> +
> +#define OP_OPR_ALIVE			cpu_to_le16(0x0010)
> +#define OP_OPR_CMD_ACK			cpu_to_le16(0x001F)
> +#define OP_OPR_CMD_NACK			cpu_to_le16(0x0020)
> +#define OP_TST_MEM_DUMP			cpu_to_le16(0x0043)
> +
> +#define CMD_FLAG_PADDING_256		0x80
> +
> +#define FW_HCMD_BLOCK_SIZE      	256
> +
> +struct msg_hdr {
> +	u8 type;
> +	u8 category;
> +	__le16 opcode;
> +	u8 seqnum;
> +	u8 flags;
> +	__le16 length;
> +} __attribute__((__packed__));
> +
> +struct log_hdr {
> +	__le32 timestamp;
> +	u8 severity;
> +	u8 logsource;
> +	__le16 reserved;
> +} __attribute__((__packed__));
> +
> +struct mdump_hdr {
> +	u8 dmpid;
> +	u8 frag;
> +	__le16 size;
> +	__le32 addr;
> +} __attribute__((__packed__));
> +
> +struct top_msg {
> +	struct msg_hdr hdr;
> +	union {
> +		/* D2H messages */
> +		struct {
> +			struct log_hdr log_hdr;
> +			u8 data[1];
> +		} __attribute__((__packed__)) log;
> +
> +		struct {
> +			struct log_hdr log_hdr;
> +			struct mdump_hdr md_hdr;
> +			u8 data[1];
> +		} __attribute__((__packed__)) mdump;
> +
> +		/* H2D messages */
> +		struct {
> +			u8 logsource;
> +			u8 sevmask;
> +		} __attribute__((__packed__)) logdefs[FW_LOG_SRC_MAX];
> +		struct mdump_hdr mdump_req;
> +	} u;
> +} __attribute__((__packed__));
> +
> +
> +#endif /* __FWMSG_H__ */
> diff --git a/drivers/misc/iwmc3200top/iwmc3200top.h b/drivers/misc/iwmc3200top/iwmc3200top.h
> new file mode 100644
> index 0000000..59e4b7a
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/iwmc3200top.h
> @@ -0,0 +1,202 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/iwmc3200top.h
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#ifndef __IWMC3200TOP_H__
> +#define __IWMC3200TOP_H__
> +
> +#define DRV_NAME "iwmc3200top"
> +
> +#define IWMC_SDIO_BLK_SIZE			256
> +#define IWMC_DEFAULT_TR_BLK			64
> +#define IWMC_SDIO_DATA_ADDR			0x0
> +#define IWMC_SDIO_INTR_ENABLE_ADDR		0x14
> +#define IWMC_SDIO_INTR_STATUS_ADDR		0x13
> +#define IWMC_SDIO_INTR_CLEAR_ADDR		0x13
> +#define IWMC_SDIO_INTR_GET_SIZE_ADDR		0x2C
> +
> +#define COMM_HUB_HEADER_LENGTH 16
> +#define LOGGER_HEADER_LENGTH   10
> +
> +
> +#define BARKER_DNLOAD_BT_POS		0
> +#define BARKER_DNLOAD_BT_MSK		BIT(BARKER_DNLOAD_BT_POS)
> +#define BARKER_DNLOAD_GPS_POS		1
> +#define BARKER_DNLOAD_GPS_MSK		BIT(BARKER_DNLOAD_GPS_POS)
> +#define BARKER_DNLOAD_TOP_POS		2
> +#define BARKER_DNLOAD_TOP_MSK		BIT(BARKER_DNLOAD_TOP_POS)
> +#define BARKER_DNLOAD_RESERVED1_POS	3
> +#define BARKER_DNLOAD_RESERVED1_MSK	BIT(BARKER_DNLOAD_RESERVED1_POS)
> +#define BARKER_DNLOAD_JUMP_POS		4
> +#define BARKER_DNLOAD_JUMP_MSK		BIT(BARKER_DNLOAD_JUMP_POS)
> +#define BARKER_DNLOAD_SYNC_POS		5
> +#define BARKER_DNLOAD_SYNC_MSK		BIT(BARKER_DNLOAD_SYNC_POS)
> +#define BARKER_DNLOAD_RESERVED2_POS	6
> +#define BARKER_DNLOAD_RESERVED2_MSK	(0x3 << BARKER_DNLOAD_RESERVED2_POS)
> +#define BARKER_DNLOAD_BARKER_POS	8
> +#define BARKER_DNLOAD_BARKER_MSK	(0xffffff << BARKER_DNLOAD_BARKER_POS)
> +
> +#define IWMC_BARKER_REBOOT 	(0xdeadbe << BARKER_DNLOAD_BARKER_POS)
> +/* whole field barker */
> +#define IWMC_BARKER_ACK 	0xfeedbabe
> +
> +#define IWMC_CMD_SIGNATURE 	0xcbbc
> +
> +#define CMD_HDR_OPCODE_POS		0
> +#define CMD_HDR_OPCODE_MSK_MSK		(0xf << CMD_HDR_OPCODE_MSK_POS)
> +#define CMD_HDR_RESPONSE_CODE_POS	4
> +#define CMD_HDR_RESPONSE_CODE_MSK	(0xf << CMD_HDR_RESPONSE_CODE_POS)
> +#define CMD_HDR_USE_CHECKSUM_POS	8
> +#define CMD_HDR_USE_CHECKSUM_MSK	BIT(CMD_HDR_USE_CHECKSUM_POS)
> +#define CMD_HDR_RESPONSE_REQUIRED_POS	9
> +#define CMD_HDR_RESPONSE_REQUIRED_MSK	BIT(CMD_HDR_RESPONSE_REQUIRED_POS)
> +#define CMD_HDR_DIRECT_ACCESS_POS	10
> +#define CMD_HDR_DIRECT_ACCESS_MSK	BIT(CMD_HDR_DIRECT_ACCESS_POS)
> +#define CMD_HDR_RESERVED_POS		11
> +#define CMD_HDR_RESERVED_MSK		BIT(0x1f << CMD_HDR_RESERVED_POS)
> +#define CMD_HDR_SIGNATURE_POS		16
> +#define CMD_HDR_SIGNATURE_MSK		BIT(0xffff << CMD_HDR_SIGNATURE_POS)
> +
> +enum {
> +	IWMC_OPCODE_PING = 0,
> +	IWMC_OPCODE_READ = 1,
> +	IWMC_OPCODE_WRITE = 2,
> +	IWMC_OPCODE_JUMP = 3,
> +	IWMC_OPCODE_REBOOT = 4,
> +	IWMC_OPCODE_PERSISTENT_WRITE = 5,
> +	IWMC_OPCODE_PERSISTENT_READ = 6,
> +	IWMC_OPCODE_READ_MODIFY_WRITE = 7,
> +	IWMC_OPCODE_LAST_COMMAND = 15
> +};
> +
> +struct iwmct_fw_load_hdr {
> +	__le32 cmd;
> +	__le32 target_addr;
> +	__le32 data_size;
> +	__le32 block_chksm;
> +	u8 data[0];
> +};
> +
> +/**
> + * struct iwmct_fw_hdr
> + * holds all sw components versions
> + */
> +struct iwmct_fw_hdr {
> +	u8 top_major;
> +	u8 top_minor;
> +	u8 top_revision;
> +	u8 gps_major;
> +	u8 gps_minor;
> +	u8 gps_revision;
> +	u8 bt_major;
> +	u8 bt_minor;
> +	u8 bt_revision;
> +	u8 tic_name[31];
> +};
> +
> +/**
> + * struct iwmct_fw_sec_hdr
> + * @type: function type
> + * @data_size: section's data size
> + * @target_addr: download address
> + */
> +struct iwmct_fw_sec_hdr {
> +	u8 type[4];
> +	__le32 data_size;
> +	__le32 target_addr;
> +};
> +
> +/**
> + * struct iwmct_parser
> + * @file: fw image
> + * @file_size: fw size
> + * @cur_pos: position in file
> + * @buf: temp buf for download
> + * @buf_size: size of buf
> + * @entry_point: address to jump in fw kick-off
> + */
> +struct iwmct_parser {
> +	const u8 *file;
> +	size_t file_size;
> +	size_t cur_pos;
> +	u8 *buf;
> +	size_t buf_size;
> +	u32 entry_point;
> +	struct iwmct_fw_hdr versions;
> +};
> +
> +
> +struct iwmct_work_struct {
> +	struct list_head list;
> +	ssize_t iosize;
> +};
> +
> +struct iwmct_dbg {
> +	int blocks;
> +	bool dump;
> +	bool jump;
> +	bool direct;
> +	bool checksum;
> +	bool fw_download;
> +	int block_size;
> +	int download_trans_blks;
> +
> +	char label_fw[256];
> +};
> +
> +struct iwmct_priv {
> +	struct sdio_func *func;
> +	struct iwmct_debugfs *dbgfs;
> +	struct iwmct_parser parser;
> +	atomic_t reset;
> +	atomic_t dev_sync;
> +	u32 trans_len;
> +	u32 barker;
> +	struct iwmct_dbg dbg;
> +
> +	/* drivers work queue */
> +	struct workqueue_struct *wq;
> +	struct workqueue_struct *bus_rescan_wq;
> +	struct work_struct bus_rescan_worker;
> +	struct work_struct isr_worker;
> +
> +	/* drivers wait queue */
> +	wait_queue_head_t wait_q;
> +
> +	/* rx request list */
> +	struct list_head read_req_list;
> +};
> +
> +extern int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
> +		void *src, int count);
> +
> +extern int iwmct_fw_load(struct iwmct_priv *priv);
> +
> +extern void iwmct_dbg_init_params(struct iwmct_priv *drv);
> +extern void iwmct_dbg_init_drv_attrs(struct device_driver *drv);
> +extern void iwmct_dbg_remove_drv_attrs(struct device_driver *drv);
> +extern int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len);
> +
> +#endif  /*  __IWMC3200TOP_H__  */
> diff --git a/drivers/misc/iwmc3200top/log.c b/drivers/misc/iwmc3200top/log.c
> new file mode 100644
> index 0000000..96b5e4a
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/log.c
> @@ -0,0 +1,339 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/log.c
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/mmc/sdio_func.h>
> +#include <linux/ctype.h>
> +#include "fw-msg.h"
> +#include "iwmc3200top.h"
> +#include "log.h"
> +
> +/* Maximal hexadecimal string size of the FW memdump message */
> +#define LOG_MSG_SIZE_MAX		12400
> +
> +/* iwmct_logdefs is a global used by log macros */
> +u8 iwmct_logdefs[LOG_SRC_MAX];
> +static u8 iwmct_fw_logdefs[FW_LOG_SRC_MAX];
> +
> +
> +static int _log_set_log_filter(u8 *logdefs, int size, u8 src, u8 logmask)
> +{
> +	int i;
> +
> +	if (src < size)
> +		logdefs[src] = logmask;
> +	else if (src == LOG_SRC_ALL)
> +		for (i = 0; i < size; i++)
> +			logdefs[i] = logmask;
> +	else
> +		return -1;
> +
> +	return 0;
> +}
> +
> +
> +int iwmct_log_set_filter(u8 src, u8 logmask)
> +{
> +	return _log_set_log_filter(iwmct_logdefs, LOG_SRC_MAX, src, logmask);
> +}
> +
> +
> +int iwmct_log_set_fw_filter(u8 src, u8 logmask)
> +{
> +	return _log_set_log_filter(iwmct_fw_logdefs,
> +				   FW_LOG_SRC_MAX, src, logmask);
> +}
> +
> +
> +static int log_msg_format_hex(char *str, int slen, u8 *ibuf,
> +			      int ilen, char *pref)
> +{
> +	int pos = 0;
> +	int i;
> +	int len;
> +
> +	for (pos = 0, i = 0; pos < slen - 2 && pref[i] != '\0'; i++, pos++)
> +		str[pos] = pref[i];
> +
> +	for (i = 0; pos < slen - 2 && i < ilen; pos += len, i++)
> +		len = snprintf(&str[pos], slen - pos - 1, " %2.2X", ibuf[i]);
> +
> +	if (i < ilen)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +/*	NOTE: This function is not thread safe.
> +	Currently it's called only from sdio rx worker - no race there
> +*/
> +void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len)
> +{
> +	struct top_msg *msg;
> +	static char logbuf[LOG_MSG_SIZE_MAX];
> +
> +	msg = (struct top_msg *)buf;
> +
> +	if (len < sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr)) {
> +		LOG_ERROR(priv, FW_MSG, "Log message from TOP "
> +			  "is too short %d (expected %zd)\n",
> +			  len, sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr));
> +		return;
> +	}
> +
> +	if (!(iwmct_fw_logdefs[msg->u.log.log_hdr.logsource] &
> +		BIT(msg->u.log.log_hdr.severity)) ||
> +	    !(iwmct_logdefs[LOG_SRC_FW_MSG] & BIT(msg->u.log.log_hdr.severity)))
> +		return;
> +
> +	switch (msg->hdr.category) {
> +	case COMM_CATEGORY_TESTABILITY:
> +		if (!(iwmct_logdefs[LOG_SRC_TST] &
> +		      BIT(msg->u.log.log_hdr.severity)))
> +			return;
> +		if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
> +				       le16_to_cpu(msg->hdr.length) +
> +				       sizeof(msg->hdr), "<TST>"))
> +			LOG_WARNING(priv, TST,
> +				  "TOP TST message is too long, truncating...");
> +		LOG_WARNING(priv, TST, "%s\n", logbuf);
> +		break;
> +	case COMM_CATEGORY_DEBUG:
> +		if (msg->hdr.opcode == OP_DBG_ZSTR_MSG)
> +			LOG_INFO(priv, FW_MSG, "%s %s", "<DBG>",
> +				       ((u8 *)msg) + sizeof(msg->hdr)
> +					+ sizeof(msg->u.log.log_hdr));
> +		else {
> +			if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
> +					le16_to_cpu(msg->hdr.length)
> +						+ sizeof(msg->hdr),
> +					"<DBG>"))
> +				LOG_WARNING(priv, FW_MSG,
> +					"TOP DBG message is too long,"
> +					"truncating...");
> +			LOG_WARNING(priv, FW_MSG, "%s\n", logbuf);
> +		}
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +static int _log_get_filter_str(u8 *logdefs, int logdefsz, char *buf, int size)
> +{
> +	int i, pos, len;
> +	for (i = 0, pos = 0; (pos < size-1) && (i < logdefsz); i++) {
> +		len = snprintf(&buf[pos], size - pos - 1, "0x%02X%02X,",
> +				i, logdefs[i]);
> +		pos += len;
> +	}
> +	buf[pos-1] = '\n';
> +	buf[pos] = '\0';
> +
> +	if (i < logdefsz)
> +		return -1;
> +	return 0;
> +}
> +
> +int log_get_filter_str(char *buf, int size)
> +{
> +	return _log_get_filter_str(iwmct_logdefs, LOG_SRC_MAX, buf, size);
> +}
> +
> +int log_get_fw_filter_str(char *buf, int size)
> +{
> +	return _log_get_filter_str(iwmct_fw_logdefs, FW_LOG_SRC_MAX, buf, size);
> +}
> +
> +#define HEXADECIMAL_RADIX	16
> +#define LOG_SRC_FORMAT		7 /* log level is in format of "0xXXXX," */
> +
> +ssize_t show_iwmct_log_level(struct device *d,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct iwmct_priv *priv = d->driver_data;
> +	char *str_buf;
> +	int buf_size;
> +	ssize_t ret = -EAGAIN;
> +
> +	buf_size = (LOG_SRC_FORMAT * LOG_SRC_MAX) + 1;
> +	str_buf = kzalloc(buf_size, GFP_KERNEL);
> +	if (!str_buf) {
> +		LOG_ERROR(priv, DEBUGFS,
> +			"failed to allocate %d bytes\n", buf_size);
> +		goto exit;
> +	}
> +
> +	if (log_get_filter_str(str_buf, buf_size) < 0)
> +		goto exit;
> +
> +	ret = sprintf(buf, "%s", str_buf);
> +
> +exit:
> +	kfree(str_buf);
> +	return ret;
> +}
> +
> +ssize_t store_iwmct_log_level(struct device *d,
> +			struct device_attribute *attr,
> +			const char *buf, size_t count)
> +{
> +	struct iwmct_priv *priv = d->driver_data;
> +	char *token, *str_buf = NULL;
> +	long val;
> +	u8 src, mask;
> +
> +	if (!count)
> +		goto err;
> +
> +	str_buf = kzalloc(count, GFP_KERNEL);
> +	if (!str_buf) {
> +		LOG_ERROR(priv, DEBUGFS,
> +			"failed to allocate %zd bytes\n", count);
> +		goto err;
> +	}
> +
> +	memcpy(str_buf, buf, count);
> +
> +	while ((token = strsep(&str_buf, ",")) != NULL) {
> +		while (isspace(*token))
> +			++token;
> +		if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
> +			LOG_ERROR(priv, DEBUGFS,
> +				  "failed to convert string to long %s\n",
> +				  token);
> +			goto err;
> +		}
> +
> +		mask  = val & 0xFF;
> +		src = (val & 0XFF00) >> 8;
> +		iwmct_log_set_filter(src, mask);
> +	}
> +
> +	kfree(str_buf);
> +	return count;
> +
> +err:
> +	kfree(str_buf);
> +	return -EAGAIN;
> +}
> +
> +ssize_t show_iwmct_log_level_fw(struct device *d,
> +			struct device_attribute *attr, char *buf)
> +{
> +	struct iwmct_priv *priv = d->driver_data;
> +	char *str_buf;
> +	int buf_size;
> +	ssize_t ret = -EAGAIN;
> +
> +	buf_size = (LOG_SRC_FORMAT * FW_LOG_SRC_MAX) + 2;
> +
> +	str_buf = kzalloc(buf_size, GFP_KERNEL);
> +	if (!str_buf) {
> +		LOG_ERROR(priv, DEBUGFS,
> +			"failed to allocate %d bytes\n", buf_size);
> +		goto exit;
> +	}
> +
> +	if (log_get_fw_filter_str(str_buf, buf_size) < 0)
> +		goto exit;
> +
> +	ret = sprintf(buf, "%s", str_buf);
> +
> +exit:
> +	kfree(str_buf);
> +	return ret;
> +}
> +
> +ssize_t store_iwmct_log_level_fw(struct device *d,
> +			struct device_attribute *attr,
> +			const char *buf, size_t count)
> +{
> +	struct iwmct_priv *priv = d->driver_data;
> +	char *token, *str_buf = NULL;
> +	long val;
> +	u8 src, mask;
> +	struct top_msg cmd;
> +	u16 cmdlen = 0;
> +	int i, rc;
> +
> +	if (!count)
> +		goto err;
> +
> +	str_buf = kzalloc(count, GFP_KERNEL);
> +	if (!str_buf) {
> +		LOG_ERROR(priv, DEBUGFS,
> +			"failed to allocate %zd bytes\n", count);
> +		goto err;
> +	}
> +
> +	memcpy(str_buf, buf, count);
> +
> +	cmd.hdr.type = COMM_TYPE_H2D;
> +	cmd.hdr.category = COMM_CATEGORY_DEBUG;
> +	cmd.hdr.opcode = CMD_DBG_LOG_LEVEL;
> +
> +	for (i = 0; ((token = strsep(&str_buf, ",")) != NULL) &&
> +		     (i < FW_LOG_SRC_MAX); i++) {
> +
> +		while (isspace(*token))
> +			++token;
> +
> +		if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
> +			LOG_ERROR(priv, DEBUGFS,
> +				  "failed to convert string to long %s\n",
> +				  token);
> +			goto err;
> +		}
> +
> +		mask  = val & 0xFF; /* LSB */
> +		src = (val & 0XFF00) >> 8; /* 2nd least significant byte. */
> +		iwmct_log_set_fw_filter(src, mask);
> +
> +		cmd.u.logdefs[i].logsource = src;
> +		cmd.u.logdefs[i].sevmask = mask;
> +	}
> +
> +	cmd.hdr.length = cpu_to_le16(i * sizeof(cmd.u.logdefs[0]));
> +	cmdlen = (i * sizeof(cmd.u.logdefs[0]) + sizeof(cmd.hdr));
> +
> +	rc = iwmct_send_hcmd(priv, (u8 *) &cmd, cmdlen);
> +	if (rc) {
> +		LOG_ERROR(priv, DEBUGFS,
> +			  "Failed to send %d bytes of fwcmd, rc=%d\n",
> +			  cmdlen, rc);
> +		goto err;
> +	} else
> +		LOG_INFO(priv, DEBUGFS, "fwcmd sent (%d bytes)\n", cmdlen);
> +
> +	kfree(str_buf);
> +	return count;
> +
> +err:
> +	kfree(str_buf);
> +	return -EAGAIN;
> +}
> +
> diff --git a/drivers/misc/iwmc3200top/log.h b/drivers/misc/iwmc3200top/log.h
> new file mode 100644
> index 0000000..aba8121
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/log.h
> @@ -0,0 +1,158 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/log.h
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#ifndef __LOG_H__
> +#define __LOG_H__
> +
> +
> +/* log severity:
> + * The log levels here match FW log levels
> + * so values need to stay as is */
> +#define LOG_SEV_CRITICAL		0
> +#define LOG_SEV_ERROR			1
> +#define LOG_SEV_WARNING			2
> +#define LOG_SEV_INFO			3
> +#define LOG_SEV_INFOEX			4
> +
> +#define LOG_SEV_FILTER_ALL		\
> +	(BIT(LOG_SEV_CRITICAL) |	\
> +	 BIT(LOG_SEV_ERROR)    |	\
> +	 BIT(LOG_SEV_WARNING)  | 	\
> +	 BIT(LOG_SEV_INFO)     |	\
> +	 BIT(LOG_SEV_INFOEX))
> +
> +/* log source */
> +#define LOG_SRC_INIT			0
> +#define LOG_SRC_DEBUGFS			1
> +#define LOG_SRC_FW_DOWNLOAD		2
> +#define LOG_SRC_FW_MSG			3
> +#define LOG_SRC_TST			4
> +#define LOG_SRC_IRQ			5
> +
> +#define	LOG_SRC_MAX			6
> +#define	LOG_SRC_ALL			0xFF
> +
> +/**
> + * Default intitialization runtime log level
> + */
> +#ifndef LOG_SEV_FILTER_RUNTIME
> +#define LOG_SEV_FILTER_RUNTIME			\
> +	(BIT(LOG_SEV_CRITICAL)	|		\
> +	 BIT(LOG_SEV_ERROR)	|		\
> +	 BIT(LOG_SEV_WARNING))
> +#endif
> +
> +#ifndef FW_LOG_SEV_FILTER_RUNTIME
> +#define FW_LOG_SEV_FILTER_RUNTIME	LOG_SEV_FILTER_ALL
> +#endif
> +
> +#ifdef CONFIG_IWMC3200TOP_DEBUG
> +/**
> + * Log macros
> + */
> +
> +#define priv2dev(priv) (&(priv->func)->dev)
> +
> +#define LOG_CRITICAL(priv, src, fmt, args...)				\
> +do {									\
> +	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_CRITICAL))	\
> +		dev_crit(priv2dev(priv), "%s %d: " fmt,			\
> +			__func__, __LINE__, ##args);			\
> +} while (0)
> +
> +#define LOG_ERROR(priv, src, fmt, args...)				\
> +do {									\
> +	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_ERROR))	\
> +		dev_err(priv2dev(priv), "%s %d: " fmt,			\
> +			__func__, __LINE__, ##args);			\
> +} while (0)
> +
> +#define LOG_WARNING(priv, src, fmt, args...)				\
> +do {									\
> +	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_WARNING))	\
> +		dev_warn(priv2dev(priv), "%s %d: " fmt,			\
> +			 __func__, __LINE__, ##args);			\
> +} while (0)
> +
> +#define LOG_INFO(priv, src, fmt, args...)				\
> +do {									\
> +	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFO))		\
> +		dev_info(priv2dev(priv), "%s %d: " fmt,			\
> +			 __func__, __LINE__, ##args);			\
> +} while (0)
> +
> +#define LOG_INFOEX(priv, src, fmt, args...)				\
> +do {									\
> +	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))	\
> +		dev_dbg(priv2dev(priv), "%s %d: " fmt,			\
> +			 __func__, __LINE__, ##args);			\
> +} while (0)
> +
> +#define LOG_HEXDUMP(src, ptr, len)					\
> +do {									\
> +	if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFOEX))	\
> +		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,	\
> +				16, 1, ptr, len, false);		\
> +} while (0)
> +
> +void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len);
> +
> +extern u8 iwmct_logdefs[];
> +
> +int iwmct_log_set_filter(u8 src, u8 logmask);
> +int iwmct_log_set_fw_filter(u8 src, u8 logmask);
> +
> +ssize_t show_iwmct_log_level(struct device *d,
> +			struct device_attribute *attr, char *buf);
> +ssize_t store_iwmct_log_level(struct device *d,
> +			struct device_attribute *attr,
> +			const char *buf, size_t count);
> +ssize_t show_iwmct_log_level_fw(struct device *d,
> +			struct device_attribute *attr, char *buf);
> +ssize_t store_iwmct_log_level_fw(struct device *d,
> +			struct device_attribute *attr,
> +			const char *buf, size_t count);
> +
> +#else
> +
> +#define LOG_CRITICAL(priv, src, fmt, args...)
> +#define LOG_ERROR(priv, src, fmt, args...)
> +#define LOG_WARNING(priv, src, fmt, args...)
> +#define LOG_INFO(priv, src, fmt, args...)
> +#define LOG_INFOEX(priv, src, fmt, args...)
> +#define LOG_HEXDUMP(src, ptr, len)
> +
> +static inline void iwmct_log_top_message(struct iwmct_priv *priv,
> +					 u8 *buf, int len) {}
> +static inline int iwmct_log_set_filter(u8 src, u8 logmask) { return 0; }
> +static inline int iwmct_log_set_fw_filter(u8 src, u8 logmask) { return 0; }
> +
> +#endif /* CONFIG_IWMC3200TOP_DEBUG */
> +
> +int log_get_filter_str(char *buf, int size);
> +int log_get_fw_filter_str(char *buf, int size);
> +
> +#endif /* __LOG_H__ */

Seriously. Please just use dynamic_printk and lets remove all this log
infrastructure. It is way too much overhead for too little benefit.

> diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c
> new file mode 100644
> index 0000000..09f8d06
> --- /dev/null
> +++ b/drivers/misc/iwmc3200top/main.c
> @@ -0,0 +1,702 @@
> +/*
> + * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
> + * drivers/misc/iwmc3200top/main.c
> + *
> + * Copyright (C) 2009 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
> + *  -
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/mmc/sdio_ids.h>
> +#include <linux/mmc/sdio_func.h>
> +#include <linux/mmc/sdio.h>
> +
> +#include "iwmc3200top.h"
> +#include "log.h"
> +#include "fw-msg.h"
> +#include "debugfs.h"
> +
> +
> +#define DRIVER_DESCRIPTION "Intel(R) IWMC 3200 Top Driver"
> +#define DRIVER_COPYRIGHT "Copyright (c) 2008 Intel Corporation."
> +
> +#define IWMCT_VERSION "0.1.62"
> +
> +#ifdef REPOSITORY_LABEL
> +#define RL REPOSITORY_LABEL
> +#else
> +#define RL ""
> +#endif
> +
> +#ifdef CONFIG_IWMC3200TOP_DEBUG
> +#define VD "-d"
> +#else
> +#define VD
> +#endif
> +
> +#define DRIVER_VERSION IWMCT_VERSION "-"  __stringify(RL) VD
> +
> +MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
> +MODULE_VERSION(DRIVER_VERSION);
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR(DRIVER_COPYRIGHT);
> +
> +
> +#ifndef SDIO_DEVICE_ID_INTEL_IWMC3200TOP
> +#define SDIO_DEVICE_ID_INTEL_IWMC3200TOP	0x1404
> +#endif
> +
> +/*
> + * This workers main task is to wait for OP_OPR_ALIVE
> + * from TOP FW until ALIVE_MSG_TIMOUT timeout is elapsed.
> + * When OP_OPR_ALIVE received it will issue
> + * a call to "bus_rescan_devices".
> + */
> +static void iwmct_rescan_worker(struct work_struct *ws)
> +{
> +	struct iwmct_priv *priv;
> +	int ret;
> +
> +	priv = container_of(ws, struct iwmct_priv, bus_rescan_worker);
> +
> +	LOG_INFO(priv, FW_MSG, "Calling bus_rescan\n");
> +
> +	ret = bus_rescan_devices(priv->func->dev.bus);
> +	if (ret < 0)
> +		LOG_INFO(priv, FW_DOWNLOAD, "bus_rescan_devices FAILED!!!\n");
> +}
> +
> +static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg)
> +{
> +	switch (msg->hdr.opcode) {
> +	case OP_OPR_ALIVE:
> +		LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n");
> +		queue_work(priv->bus_rescan_wq, &priv->bus_rescan_worker);
> +		break;
> +	default:
> +		LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n",
> +			msg->hdr.opcode);
> +		break;
> +	}
> +}
> +
> +
> +static void handle_top_message(struct iwmct_priv *priv, u8 *buf, int len)
> +{
> +	struct top_msg *msg;
> +
> +	msg = (struct top_msg *)buf;
> +
> +	if (msg->hdr.type != COMM_TYPE_D2H) {
> +		LOG_ERROR(priv, FW_MSG,
> +			"Message from TOP with invalid message type 0x%X\n",
> +			msg->hdr.type);
> +		return;
> +	}
> +
> +	if (len < sizeof(msg->hdr)) {
> +		LOG_ERROR(priv, FW_MSG,
> +			"Message from TOP is too short for message header "
> +			"received %d bytes, expected at least %zd bytes\n",
> +			len, sizeof(msg->hdr));
> +		return;
> +	}
> +
> +	if (len < le16_to_cpu(msg->hdr.length) + sizeof(msg->hdr)) {
> +		LOG_ERROR(priv, FW_MSG,
> +			"Message length (%d bytes) is shorter than "
> +			"in header (%d bytes)\n",
> +			len, le16_to_cpu(msg->hdr.length));
> +		return;
> +	}
> +
> +	switch (msg->hdr.category) {
> +	case COMM_CATEGORY_OPERATIONAL:
> +		op_top_message(priv, (struct top_msg *)buf);
> +		break;
> +
> +	case COMM_CATEGORY_DEBUG:
> +	case COMM_CATEGORY_TESTABILITY:
> +	case COMM_CATEGORY_DIAGNOSTICS:
> +		iwmct_log_top_message(priv, buf, len);
> +		break;
> +
> +	default:
> +		LOG_ERROR(priv, FW_MSG,
> +			"Message from TOP with unknown category 0x%X\n",
> +			msg->hdr.category);
> +		break;
> +	}
> +}
> +
> +int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len)
> +{
> +	int ret;
> +	u8 *buf;
> +
> +	LOG_INFOEX(priv, FW_MSG, "Sending hcmd:\n");
> +
> +	/* add padding to 256 for IWMC */
> +	((struct top_msg *)cmd)->hdr.flags |= CMD_FLAG_PADDING_256;
> +
> +	LOG_HEXDUMP(FW_MSG, cmd, len);
> +
> +	if (len > FW_HCMD_BLOCK_SIZE) {
> +		LOG_ERROR(priv, FW_MSG, "size %d exceeded hcmd max size %d\n",
> +			  len, FW_HCMD_BLOCK_SIZE);
> +		return -1;
> +	}
> +
> +	buf = kzalloc(FW_HCMD_BLOCK_SIZE, GFP_KERNEL);
> +	if (!buf) {
> +		LOG_ERROR(priv, FW_MSG, "kzalloc error, buf size %d\n",
> +			  FW_HCMD_BLOCK_SIZE);
> +		return -1;
> +	}
> +
> +	memcpy(buf, cmd, len);
> +
> +	sdio_claim_host(priv->func);
> +	ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, buf,
> +			       FW_HCMD_BLOCK_SIZE);
> +	sdio_release_host(priv->func);
> +
> +	kfree(buf);
> +	return ret;
> +}
> +
> +int iwmct_tx(struct iwmct_priv *priv, unsigned int addr,
> +	void *src, int count)
> +{
> +	int ret;
> +
> +	sdio_claim_host(priv->func);
> +	ret = sdio_memcpy_toio(priv->func, addr, src, count);
> +	sdio_release_host(priv->func);
> +
> +	return ret;
> +}
> +
> +static void iwmct_irq_read_worker(struct work_struct *ws)
> +{
> +	struct iwmct_priv *priv;
> +	struct iwmct_work_struct *read_req;
> +	__le32 *buf = NULL;
> +	int ret, val, i;
> +	int iosize;
> +	u32 barker;
> +
> +	priv = container_of(ws, struct iwmct_priv, isr_worker);
> +
> +	LOG_INFO(priv, IRQ, "enter iwmct_irq_read_worker %p\n", ws);
> +
> +	/* --------------------- Handshake with device -------------------- */
> +	sdio_claim_host(priv->func);
> +
> +	/* all list manipulations have to be protected by
> +	 * sdio_claim_host/sdio_release_host */
> +	if (list_empty(&priv->read_req_list)) {
> +		LOG_ERROR(priv, IRQ, "read_req_list empty in read worker\n");
> +		goto exit_release;
> +	}
> +
> +	read_req = list_entry(priv->read_req_list.next,
> +			      struct iwmct_work_struct, list);
> +
> +	list_del(&read_req->list);
> +	iosize = read_req->iosize;
> +	kfree(read_req);
> +
> +	buf = kzalloc(iosize, GFP_KERNEL);
> +	if (!buf) {
> +		LOG_ERROR(priv, IRQ, "kzalloc error, buf size %d\n", iosize);
> +		goto exit_release;
> +	}
> +
> +	LOG_INFO(priv, IRQ, "iosize=%d, buf=%p, func=%d\n",
> +				iosize, buf, priv->func->num);
> +
> +	/* read from device */
> +	ret = sdio_memcpy_fromio(priv->func, buf, IWMC_SDIO_DATA_ADDR, iosize);
> +	if (ret) {
> +		LOG_ERROR(priv, IRQ, "error %d reading buffer\n", ret);
> +		goto exit_release;
> +	}
> +
> +	LOG_HEXDUMP(IRQ, (u8 *)buf, iosize);
> +
> +	barker = le32_to_cpu(buf[0]);
> +	if (barker != IWMC_BARKER_ACK &&
> +	   (barker & BARKER_DNLOAD_BARKER_MSK) != IWMC_BARKER_REBOOT) {
> +		/* Handle Top Commhub message.
> +		 * Current handling - treat all message as
> +		 * logger messages and print the context as a string. */
> +		sdio_release_host(priv->func);
> +		handle_top_message(priv, (u8 *)buf, iosize);
> +		goto exit;
> +	}
> +
> +	/* verify basic barker sanity */
> +	for (i = 1; i < 4; i++)
> +		if (buf[i] != buf[0]) {
> +			LOG_ERROR(priv, IRQ, "Corrupted barker,"
> +					     "buf[%d]=%x buf[0]=%x\n",
> +					     i, buf[i], buf[0]);
> +			goto exit_release;
> +		}
> +
> +	val = atomic_read(&priv->dev_sync);
> +
> +	switch (val) {
> +	case 0:
> +		/* we expect to recieve REBOOT BARKER */
> +		if ((barker & BARKER_DNLOAD_BARKER_MSK) != IWMC_BARKER_REBOOT) {
> +			LOG_ERROR(priv, IRQ, "Expecting for reboot barker %x,"
> +					"but got %x\n",
> +					IWMC_BARKER_REBOOT,
> +					(barker & BARKER_DNLOAD_BARKER_MSK));
> +			goto exit_release;
> +		}
> +
> +		LOG_INFO(priv, IRQ, "Recieved reboot barker: %x\n", barker);
> +		priv->barker = barker;
> +
> +		if (barker & BARKER_DNLOAD_SYNC_MSK) {
> +			/* Send the same barker back */
> +			ret = sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR,
> +					       buf, iosize);
> +			if (ret) {
> +				LOG_ERROR(priv, IRQ,
> +					 "error %d echoing barker\n", ret);
> +				goto exit_release;
> +			}
> +			LOG_INFO(priv, IRQ, "Echoing barker to device\n");
> +			atomic_inc(&priv->dev_sync);
> +			goto exit_release;
> +		}
> +		break;
> +
> +	case 1:
> +		/* we expect to recieve ACK BARKER */
> +		if (barker != IWMC_BARKER_ACK) {
> +			LOG_INFO(priv, IRQ, "Expecting for ACK barker[%x],"
> +				 "got this instead %x\n",
> +				 IWMC_BARKER_ACK, barker);
> +			goto exit_release;
> +		}
> +		kfree(buf);
> +		atomic_set(&priv->dev_sync, 0);
> +		atomic_set(&priv->reset, 0);
> +		break;
> +
> +	default:
> +		LOG_INFO(priv, IRQ, "Wrong dev_sync %d\n", val);
> +		break;
> +	}
> +
> +	sdio_release_host(priv->func);
> +
> +
> +	LOG_INFO(priv, IRQ, "barker download request 0x%x is:\n", priv->barker);
> +	LOG_INFO(priv, IRQ, "*******  Top FW %s requested ********\n",
> +			(priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
> +	LOG_INFO(priv, IRQ, "*******  GPS FW %s requested ********\n",
> +			(priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
> +	LOG_INFO(priv, IRQ, "*******  BT FW %s requested ********\n",
> +			(priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");
> +
> +	if (priv->dbg.fw_download)
> +		iwmct_fw_load(priv);
> +	else
> +		LOG_ERROR(priv, IRQ, "FW download not allowed\n");
> +
> +	return;
> +
> +exit_release:
> +	sdio_release_host(priv->func);
> +exit:
> +	kfree(buf);
> +	LOG_INFO(priv, IRQ, "exit iwmct_irq_read_worker\n");
> +}
> +
> +static void iwmct_irq(struct sdio_func *func)
> +{
> +	struct iwmct_priv *priv;
> +	int val, ret;
> +	int iosize;
> +	int addr = IWMC_SDIO_INTR_GET_SIZE_ADDR;
> +	struct iwmct_work_struct *read_req;
> +
> +	priv = sdio_get_drvdata(func);
> +
> +	LOG_INFO(priv, IRQ, "enter iwmct_irq\n");
> +
> +	/* read the function's status register */
> +	val = sdio_readb(func, IWMC_SDIO_INTR_STATUS_ADDR, &ret);
> +
> +	LOG_INFO(priv, IRQ, "iir value = %d, ret=%d\n", val, ret);
> +
> +	if (!val) {
> +		LOG_ERROR(priv, IRQ, "iir = 0, exiting ISR\n");
> +		goto exit_clear_intr;
> +	}
> +
> +
> +	/*
> +	 * read 2 bytes of the transaction size
> +	 * IMPORTANT: sdio transaction size has to be read before clearing
> +	 * sdio interrupt!!!
> +	 */
> +	val = sdio_readb(priv->func, addr++, &ret);
> +	iosize = val;
> +	val = sdio_readb(priv->func, addr++, &ret);
> +	iosize += val << 8;
> +
> +	LOG_INFO(priv, IRQ, "READ size %d\n", iosize);
> +
> +	if (iosize == 0) {
> +		LOG_ERROR(priv, IRQ, "READ size %d, exiting ISR\n", iosize);
> +		goto exit_clear_intr;
> +	}
> +
> +	/* allocate a work structure to pass iosize to the worker */
> +	read_req = kzalloc(sizeof(struct iwmct_work_struct), GFP_KERNEL);
> +	if (!read_req) {
> +		LOG_ERROR(priv, IRQ, "failed to allocate read_req, exit ISR\n");
> +		goto exit_clear_intr;
> +	}
> +
> +	INIT_LIST_HEAD(&read_req->list);
> +	read_req->iosize = iosize;
> +
> +	list_add_tail(&priv->read_req_list, &read_req->list);
> +
> +	/* clear the function's interrupt request bit (write 1 to clear) */
> +	sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
> +
> +	queue_work(priv->wq, &priv->isr_worker);
> +
> +	LOG_INFO(priv, IRQ, "exit iwmct_irq\n");
> +
> +	return;
> +
> +exit_clear_intr:
> +	/* clear the function's interrupt request bit (write 1 to clear) */
> +	sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
> +}
> +
> +
> +static int blocks;
> +module_param(blocks, int, 0604);
> +MODULE_PARM_DESC(blocks, "max_blocks_to_send");
> +
> +static int dump;
> +module_param(dump, bool, 0604);
> +MODULE_PARM_DESC(dump, "dump_hex_content");
> +
> +static int jump = 1;
> +module_param(jump, bool, 0604);
> +
> +static int direct = 1;
> +module_param(direct, bool, 0604);
> +
> +static int checksum = 1;
> +module_param(checksum, bool, 0604);
> +
> +static int fw_download = 1;
> +module_param(fw_download, bool, 0604);
> +
> +static int block_size = IWMC_SDIO_BLK_SIZE;
> +module_param(block_size, int, 0404);
> +
> +static int download_trans_blks = IWMC_DEFAULT_TR_BLK;
> +module_param(download_trans_blks, int, 0604);
> +
> +static int rubbish_barker;
> +module_param(rubbish_barker, bool, 0604);

Most of them are missing descriptions. And do we really need them? What
cases are they trying to work around?

> +
> +#ifdef CONFIG_IWMC3200TOP_DEBUG
> +static int log_level[LOG_SRC_MAX];
> +static unsigned int log_level_argc;
> +module_param_array(log_level, int, &log_level_argc, 0604);
> +MODULE_PARM_DESC(log_level, "log_level");
> +
> +static int log_level_fw[FW_LOG_SRC_MAX];
> +static unsigned int log_level_fw_argc;
> +module_param_array(log_level_fw, int, &log_level_fw_argc, 0604);
> +MODULE_PARM_DESC(log_level_fw, "log_level_fw");
> +#endif
> +
> +void iwmct_dbg_init_params(struct iwmct_priv *priv)
> +{
> +#ifdef CONFIG_IWMC3200TOP_DEBUG
> +	int i;
> +
> +	for (i = 0; i < log_level_argc; i++) {
> +		dev_notice(&priv->func->dev, "log_level[%d]=0x%X\n",
> +						i, log_level[i]);
> +		iwmct_log_set_filter((log_level[i] >> 8) & 0xFF,
> +			       log_level[i] & 0xFF);
> +	}
> +	for (i = 0; i < log_level_fw_argc; i++) {
> +		dev_notice(&priv->func->dev, "log_level_fw[%d]=0x%X\n",
> +						i, log_level_fw[i]);
> +		iwmct_log_set_fw_filter((log_level_fw[i] >> 8) & 0xFF,
> +				  log_level_fw[i] & 0xFF);
> +	}
> +#endif
> +
> +	priv->dbg.blocks = blocks;
> +	LOG_INFO(priv, INIT, "blocks=%d\n", blocks);
> +	priv->dbg.dump = (bool)dump;
> +	LOG_INFO(priv, INIT, "dump=%d\n", dump);
> +	priv->dbg.jump = (bool)jump;
> +	LOG_INFO(priv, INIT, "jump=%d\n", jump);
> +	priv->dbg.direct = (bool)direct;
> +	LOG_INFO(priv, INIT, "direct=%d\n", direct);
> +	priv->dbg.checksum = (bool)checksum;
> +	LOG_INFO(priv, INIT, "checksum=%d\n", checksum);
> +	priv->dbg.fw_download = (bool)fw_download;
> +	LOG_INFO(priv, INIT, "fw_download=%d\n", fw_download);
> +	priv->dbg.block_size = block_size;
> +	LOG_INFO(priv, INIT, "block_size=%d\n", block_size);
> +	priv->dbg.download_trans_blks = download_trans_blks;
> +	LOG_INFO(priv, INIT, "download_trans_blks=%d\n", download_trans_blks);
> +}
> +
> +/*****************************************************************************
> + *
> + * sysfs attributes
> + *
> + *****************************************************************************/
> +static ssize_t show_iwmct_fw_version(struct device *d,
> +				  struct device_attribute *attr, char *buf)
> +{
> +	return sprintf(buf, "%s\n",
> +		       ((struct iwmct_priv *)d->driver_data)->dbg.label_fw);
> +}
> +static DEVICE_ATTR(cc_label_fw, S_IRUGO, show_iwmct_fw_version, NULL);
> +
> +#ifdef CONFIG_IWMC3200TOP_DEBUG
> +static DEVICE_ATTR(log_level, S_IWUSR | S_IRUGO,
> +		   show_iwmct_log_level, store_iwmct_log_level);
> +static DEVICE_ATTR(log_level_fw, S_IWUSR | S_IRUGO,
> +		   show_iwmct_log_level_fw, store_iwmct_log_level_fw);
> +#endif

First module parameters and now device attributes. Why?

> +
> +static struct attribute *iwmct_sysfs_entries[] = {
> +	&dev_attr_cc_label_fw.attr,
> +#ifdef CONFIG_IWMC3200TOP_DEBUG
> +	&dev_attr_log_level.attr,
> +	&dev_attr_log_level_fw.attr,
> +#endif
> +	NULL
> +};
> +
> +static struct attribute_group iwmct_attribute_group = {
> +	.name = NULL,		/* put in device directory */
> +	.attrs = iwmct_sysfs_entries,
> +};
> +
> +
> +static int iwmct_probe(struct sdio_func *func,
> +			   const struct sdio_device_id *id)
> +{
> +	struct iwmct_priv *priv;
> +	int ret;
> +	int val = 1;
> +	int addr = IWMC_SDIO_INTR_ENABLE_ADDR;
> +
> +	dev_info(&func->dev, "enter iwmct_probe\n");
> +
> +	dev_info(&func->dev, "IRQ polling period id %u msecs, HZ is %d\n",
> +		jiffies_to_msecs(2147483647), HZ);

This is debug code. Don't use dev_info().

> +
> +	priv = kzalloc(sizeof(struct iwmct_priv), GFP_KERNEL);
> +	if (!priv) {
> +		dev_err(&func->dev, "kzalloc error\n");
> +		return -ENOMEM;
> +	}
> +	priv->func = func;
> +	sdio_set_drvdata(func, priv);
> +
> +	LOG_INFO(priv, INIT, "HIDR supported\n");
> +
> +	/* create drivers work queue */
> +	priv->wq = create_workqueue(DRV_NAME "_wq");
> +	priv->bus_rescan_wq = create_workqueue(DRV_NAME "_rescan_wq");
> +	INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker);
> +	INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker);
> +
> +	init_waitqueue_head(&priv->wait_q);
> +
> +	sdio_claim_host(func);
> +	/* FIXME: Remove after it is fixed in the Boot ROM upgrade */
> +	func->enable_timeout = 10;
> +
> +	/* In our HW, setting the block size also wakes up the boot rom. */
> +	ret = sdio_set_block_size(func, priv->dbg.block_size);
> +	if (ret) {
> +		LOG_ERROR(priv, INIT,
> +			"sdio_set_block_size() failure: %d\n", ret);
> +		goto error_sdio_enable;
> +	}
> +
> +	ret = sdio_enable_func(func);
> +	if (ret) {
> +		LOG_ERROR(priv, INIT, "sdio_enable_func() failure: %d\n", ret);
> +		goto error_sdio_enable;
> +	}
> +
> +	/* init reset and dev_sync states */
> +	atomic_set(&priv->reset, 0);
> +	atomic_set(&priv->dev_sync, 0);
> +
> +	/* init read req queue */
> +	INIT_LIST_HEAD(&priv->read_req_list);
> +
> +	/* process configurable parameters */
> +	iwmct_dbg_init_params(priv);
> +	ret = sysfs_create_group(&func->dev.kobj, &iwmct_attribute_group);
> +	if (ret) {
> +		LOG_ERROR(priv, INIT, "Failed to register attributes and "
> +			 "initialize module_params\n");
> +		goto error_dev_attrs;
> +	}
> +
> +	iwmct_dbgfs_register(priv, DRV_NAME);
> +
> +	if (!priv->dbg.direct && priv->dbg.download_trans_blks > 8) {
> +		LOG_INFO(priv, INIT,
> +			 "Reducing transaction to 8 blocks = 2K (from %d)\n",
> +			 priv->dbg.download_trans_blks);
> +		priv->dbg.download_trans_blks = 8;
> +	}
> +	priv->trans_len = priv->dbg.download_trans_blks * priv->dbg.block_size;
> +	LOG_INFO(priv, INIT, "Transaction length = %d\n", priv->trans_len);
> +
> +	ret = sdio_claim_irq(func, iwmct_irq);
> +	if (ret) {
> +		LOG_ERROR(priv, INIT, "sdio_claim_irq() failure: %d\n", ret);
> +		goto error_claim_irq;
> +	}
> +
> +
> +	/* Enable function's interrupt */
> +	sdio_writeb(priv->func, val, addr, &ret);
> +	if (ret) {
> +		LOG_ERROR(priv, INIT, "Failure writing to "
> +			  "Interrupt Enable Register (%d): %d\n", addr, ret);
> +		goto error_enable_int;
> +	}
> +
> +	sdio_release_host(func);
> +
> +	LOG_INFO(priv, INIT, "exit iwmct_probe\n");
> +
> +	return ret;
> +
> +error_enable_int:
> +	sdio_release_irq(func);
> +error_claim_irq:
> +	sdio_disable_func(func);
> +error_dev_attrs:
> +	iwmct_dbgfs_unregister(priv->dbgfs);
> +	sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
> +error_sdio_enable:
> +	sdio_release_host(func);
> +	return ret;
> +}
> +
> +static void iwmct_remove(struct sdio_func *func)
> +{
> +	struct iwmct_work_struct *read_req;
> +	struct iwmct_priv *priv = sdio_get_drvdata(func);
> +
> +	priv = sdio_get_drvdata(func);
> +
> +	LOG_INFO(priv, INIT, "enter\n");
> +
> +	sdio_claim_host(func);
> +	sdio_release_irq(func);
> +	sdio_release_host(func);
> +
> +	/* Safely destroy osc workqueue */
> +	destroy_workqueue(priv->bus_rescan_wq);
> +	destroy_workqueue(priv->wq);
> +
> +	sdio_claim_host(func);
> +	sdio_disable_func(func);
> +	sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
> +	iwmct_dbgfs_unregister(priv->dbgfs);
> +	sdio_release_host(func);
> +
> +	/* free read requests */
> +	while (!list_empty(&priv->read_req_list)) {
> +		read_req = list_entry(priv->read_req_list.next,
> +			struct iwmct_work_struct, list);
> +
> +		list_del(&read_req->list);
> +		kfree(read_req);
> +	}
> +
> +	kfree(priv);
> +}
> +
> +
> +static const struct sdio_device_id iwmct_ids[] = {
> +	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, SDIO_DEVICE_ID_INTEL_IWMC3200TOP)},
> +	{ /* end: all zeroes */	},
> +};
> +
> +MODULE_DEVICE_TABLE(sdio, iwmct_ids);
> +
> +static struct sdio_driver iwmct_driver = {
> +	.probe		= iwmct_probe,
> +	.remove		= iwmct_remove,
> +	.name		= DRV_NAME,
> +	.id_table	= iwmct_ids,
> +};
> +
> +static int __init iwmct_init(void)
> +{
> +	int rc;
> +
> +	/* Default log filter settings */
> +	iwmct_log_set_filter(LOG_SRC_ALL, LOG_SEV_FILTER_RUNTIME);
> +	iwmct_log_set_filter(LOG_SRC_FW_MSG, LOG_SEV_FILTER_ALL);
> +	iwmct_log_set_fw_filter(LOG_SRC_ALL, FW_LOG_SEV_FILTER_RUNTIME);
> +
> +	rc = sdio_register_driver(&iwmct_driver);
> +
> +	return rc;
> +}

Actually return sdio_register_driver() would do the same trick.

> +
> +static void __exit iwmct_exit(void)
> +{
> +	sdio_unregister_driver(&iwmct_driver);
> +}
> +
> +module_init(iwmct_init);
> +module_exit(iwmct_exit);
> +

At some point I got lost in this code. It contains more debug statements
and infrastructure than actual code as it seems. Can you please clean
this up. I mentioned it above. Just use dynamic_printk and you should be
have something clean and simple.

Regards

Marcel



^ permalink raw reply

* Re: Ath5k data aborts
From: Nick Kossifidis @ 2009-10-10 10:56 UTC (permalink / raw)
  To: Krzysztof Halasa; +Cc: linux-wireless, ath5k-devel, netdev
In-Reply-To: <m3tyy8fkda.fsf@intrepid.localdomain>

2009/10/9 Krzysztof Halasa <khc@pm.waw.pl>:
> Hi,
>
> I have done a small investigation. IXP425 (ARM) in big-endian mode,
> EABI, mini-PCI atk5k wifi card, hostapd.
>
> Atheros Communications Inc. Atheros AR5001X+ Wireless Network Adapter (rev 01)
> Subsystem: Wistron NeWeb Corp. CM9 Wireless a/b/g MiniPCI Adapter
> 168c:0013 subsystem 185f:1012
>
>
> Results:
> Bad mode in data abort handler detected
> Internal error: Oops - bad mode: 0 [#1]
> LR is at ath5k_beacon_config+0x150/0x1d4 [ath5k]
>
> This means the PCI device didn't respond on the bus or something
> like that. Obviously the card is then unusable and the system needs to
> be restarted.
>
> Bisecting (I had to modify the procedure a bit since it only started to
> show up after other unrelated code was merged) shows the guilty commit:
> e8f055f0c3ba226ca599c14c2e5fe829f6f57cbb (ath5k: Update reset code).
>
> The problem exists with 2.6.30, 2.6.31 and current Linus' tree.
>
> Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
>
> ----------------------------------------------
> 2.6.30 appears to be fixed by:
>
> --- a/drivers/net/wireless/ath5k/reset.c
> +++ b/drivers/net/wireless/ath5k/reset.c
> @@ -476,7 +476,7 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
>                (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
>                        ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
>                        ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
> -                       ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
> +                       ath5k_hw_reg_write(ah, 0x0C, AR5K_PHY_SCLOCK);
>                        ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
>                        AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
>                                AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
> @@ -490,8 +490,10 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
>                }
>
>                /* Enable sleep clock operation */
> +#if 0
>                AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
>                                AR5K_PCICFG_SLEEP_CLOCK_EN);
> +#endif
>
>        } else {
>
>
>
> The AR5K_PHY_SCLOCK brings the old value (before the commit in question)
> back, I have no idea what is it. Leaving the new value causes the second
> run of hostapd to make the driver fail, the chip seems to not respond.
> It seems the value itself may be correct (as it works with 2.6.31+) but
> there is some additional bug fixed after 2.6.30, gitk show several
> candidate patches for this.
>
>
> Only disabling AR5K_PCICFG write makes the data abort go away.
>
> ----------------------------------------------
> 2.6.31 and Linus-current only need the AR5K_PCICFG change:
>
> --- a/drivers/net/wireless/ath/ath5k/reset.c
> +++ b/drivers/net/wireless/ath/ath5k/reset.c
> @@ -489,9 +489,10 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
>                }
>
>                /* Enable sleep clock operation */
> +#if 0
>                AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
>                                AR5K_PCICFG_SLEEP_CLOCK_EN);
> -
> +#endif
>        } else {
>
>                /* Disable sleep clock operation and
>
>
> The question is, obviously, how to fix that for good. I can test the
> result.

Interesting, can you provide us with an eeprom info dump from your
card (using ath_info tool from madwifi svn) ?
It seems we need to skip sleep clock operation in your case.


-- 
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

^ permalink raw reply

* Re: [PATCH 1/3] iwmc3200top: Add Intel Wireless MultiCom 3200 top driver.
From: Tomas Winkler @ 2009-10-10  9:38 UTC (permalink / raw)
  To: davem, linville, netdev, linux-wireless, linux-mmc
  Cc: yi.zhu, inaky.perez-gonzalez, cindy.h.kao, guy.cohen,
	ron.rindjunsky, Tomas Winkler
In-Reply-To: <1253662724-16497-2-git-send-email-tomas.winkler@intel.com>

On Wed, Sep 23, 2009 at 1:38 AM, Tomas Winkler <tomas.winkler@intel.com> wrote:
> This patch adds Intel Wireless MultiCom 3200 top driver.
> IWMC3200 is 4Wireless Com CHIP (GPS/BT/WiFi/WiMAX).
> Top driver is responsible for device initialization and firmware download.
> Firmware handled by top is responsible for top itself and
> as well as bluetooth and GPS coms. (Wifi and WiMax provide their own
> firmware)
> In addition top driver is used to retrieve firmware logs
> and supports other debugging features
>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>

Dave,
are you going to merge this one?
iwmc3200wifi and i200m-sdio which are already merged are usless without it

Thanks
Tomas

^ permalink raw reply

* Re: mmotm 2009-10-09-01-07 - iwl3945 fails to do firmware load request
From: Valdis.Kletnieks @ 2009-10-10  5:22 UTC (permalink / raw)
  To: Zhu Yi
  Cc: Andrew Morton, John W. Linville, linux-kernel@vger.kernel.org,
	linux-wireless@vger.kernel.org
In-Reply-To: <1255135355.3719.22.camel@debian>

[-- Attachment #1: Type: text/plain, Size: 618 bytes --]

On Sat, 10 Oct 2009 08:42:35 +0800, Zhu Yi said:

> The firmware loading happens when the user space brings the interface
> up. Can you check NM is running for the bad case?

I'm not using NM, because I've never figured out how to get it to DTRT for
my network config, so I run wpa_supplicant directly.  It's looking like
a bad update to dbus was the actual root cause.

(Did I mention how I loath dbus?  Or at least the fact that if it breaks,
everything from wireless to pulseaudio immediately craps out too.  That and
'hald' are my two favorite "only on this laptop because stuff refuses to
work without them"....)

[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply

* Re: mmotm 2009-10-09-01-07 uploaded (b43)
From: Larry Finger @ 2009-10-10  3:55 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: akpm, linux-wireless, linux-kernel
In-Reply-To: <20091009154732.af708827.rdunlap@xenotime.net>

On 10/09/2009 05:47 PM, Randy Dunlap wrote:
> 
> In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
>                  from mmotm-2009-1009-0107/drivers/net/wireless/b43/main.c:47:

These warnings occur because CONFIG_B43_LEDS is not set, probably
because CONFIG_MAC80211_LEDS is not set. See the patch in
http://marc.info/?l=linux-wireless&m=125509895406304&w=2.

Larry

^ permalink raw reply

* Re: deauthentication and disassociation nl80211 commands
From: Maxim Levitsky @ 2009-10-10  3:45 UTC (permalink / raw)
  To: hostap@lists.shmoo.com; +Cc: linux-wireless
In-Reply-To: <1254708707.24430.68.camel@maxim-laptop>

On Mon, 2009-10-05 at 04:11 +0200, Maxim Levitsky wrote: 
> Here I want to ask and summarize problems we found in thread
> 'driver_nl80211 broken again'
> 
> 
> First of all it it known that lifetime of connection to access point is
> typically:
> 
> authentication request/response
> association request/response
> 
> EAPOL 4 way handshake (for WPA)
> 
> <session>
> 
> disassociation
> deauthentication
> 
> Today kernel explicitly requests the driver to perform both
> disassociation and deauthentication in that order.
> It is also possible to do disassociation and then association, skipping
> the authentication step.
> 
> However, currently wpa_supplicant assumes that once it called
> wpa_drv_disassociate it can again start the complete connect sequence
> from the authentication.
> 
> In fact I have carefully studied the code and found that calls to
> wpa_supplicant_deauthenticate (which is the only user of
> wpa_drv_deauthenticate) only happen at deinitialization of wireless
> interface and when wpa_supplicant really has to do it, that is if there
> is a failure (mic failure for example).
> 
> My hacky patch that was rejected on the grounds that it is not right to
> introduce the driver dependent behavior might actually be the correct
> solution. It just makes the wpa_supplicant_disassociate do both
> disassociation and deauthentication, as was always assumed by the
> wpa_supplicant core.
> 
> 
> Or kernel should became smarter and do the work for wpa_supplicant. 
> 
> In this case it should work like that:
> 
> If mac80211 is already authenticated to the AP that was requested, it
> should just return success.
> However currently (and I was told that this is feature, not a bug)
> mac80211 would flatly refuse to do any scanning while it is in
> authenticated but not associated state.
> 
> If it isn't authenticated to new AP then, new authentication should be
> made.
> (and old one can be kept, but removed after a timeout)
> 
> 
> And the last question.
> When do you plan to switch officially the wpa_supplicant to
> driver_nl80211?
> 
> Currently it has this issue, and another issue that it (nl80211) reports
> signal levels in another format that NetworkManager doesn't understand.
> 
> Other that that it is faster, and especially it allows me to bring
> network up, when I press rfkill button within 4 seconds or less.
> 
> 
> Best regards,
> Maxim Levitsky
> 

Nobody uses driver_nl80211 but me?

Best regards,
Maxim Levitsky


^ permalink raw reply

* Re: mmotm 2009-10-09-01-07 - iwl3945 fails to do firmware load request
From: Zhu Yi @ 2009-10-10  0:42 UTC (permalink / raw)
  To: Valdis.Kletnieks@vt.edu
  Cc: Andrew Morton, John W. Linville, linux-kernel@vger.kernel.org,
	linux-wireless@vger.kernel.org
In-Reply-To: <16108.1255133561@turing-police.cc.vt.edu>

On Sat, 2009-10-10 at 08:12 +0800, Valdis.Kletnieks@vt.edu wrote:
> On Fri, 09 Oct 2009 01:07:49 PDT, akpm@linux-foundation.org said:
> > The mm-of-the-moment snapshot 2009-10-09-01-07 has been uploaded to
> > 
> >    http://userweb.kernel.org/~akpm/mmotm/
> 
> Broke my iwl3945 wireless card:
> 
> Good (2.6.31-mmotm0917)
> Oct  8 09:55:33 turing-police kernel: [    0.809101] iwl3945: Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux, 1.2.26ks
> Oct  8 09:55:33 turing-police kernel: [    0.809106] iwl3945: Copyright(c) 2003-2009 Intel Corporation
> Oct  8 09:55:33 turing-police kernel: [    0.809201] iwl3945 0000:0c:00.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
> Oct  8 09:55:33 turing-police kernel: [    0.879463] iwl3945 0000:0c:00.0: Tunable channels: 11 802.11bg, 13 802.11a channels
> Oct  8 09:55:33 turing-police kernel: [    0.879466] iwl3945 0000:0c:00.0: Detected Intel Wireless WiFi Link 3945ABG
> ...
> Oct  8 09:55:35 turing-police kernel: [   31.599751] iwl3945 0000:0c:00.0: firmware: requesting iwlwifi-3945-2.ucode
> Oct  8 09:55:35 turing-police kernel: [   31.697046] iwl3945 0000:0c:00.0: loaded firmware version 15.28.2.8
> Oct  8 09:55:35 turing-police kernel: [   31.777214] Registered led device: iwl-phy0::radio
> Oct  8 09:55:35 turing-police kernel: [   31.777430] Registered led device: iwl-phy0::assoc
> Oct  8 09:55:35 turing-police kernel: [   31.777545] Registered led device: iwl-phy0::RX
> Oct  8 09:55:35 turing-police kernel: [   31.777676] Registered led device: iwl-phy0::TX
> Oct  8 09:55:35 turing-police kernel: [   31.789446] ADDRCONF(NETDEV_UP): wlan0: link is not ready
> (and then wpa-supplicant is able to bring the card up when it finally gets launched by initscripts)
> 
> Bad 2.6.32-rc3-mmotm1009:
> 
> Oct  9 13:50:19 turing-police kernel: [    0.931788] iwl3945: Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux, 1.2.26ks
> Oct  9 13:50:19 turing-police kernel: [    0.944678] iwl3945: Copyright(c) 2003-2009 Intel Corporation
> Oct  9 13:50:19 turing-police kernel: [    0.957831] iwl3945 0000:0c:00.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
> Oct  9 13:50:19 turing-police kernel: [    1.038946] iwl3945 0000:0c:00.0: Tunable channels: 11 802.11bg, 13 802.11a channels
> Oct  9 13:50:19 turing-police kernel: [    1.038950] iwl3945 0000:0c:00.0: Detected Intel Wireless WiFi Link 3945ABG
> 
> We never see the firmware load request, and of course everything goes
> pear-shaped after that doesn't happen....

The firmware loading happens when the user space brings the interface
up. Can you check NM is running for the bad case?

Thanks,
-yi


^ permalink raw reply

* mmotm 2009-10-09-01-07 - iwl3945 fails to do firmware load request
From: Valdis.Kletnieks @ 2009-10-10  0:12 UTC (permalink / raw)
  To: Andrew Morton, Zhu Yi, John W. Linville; +Cc: linux-kernel, linux-wireless
In-Reply-To: <200910090830.n998Ubvv020464@imap1.linux-foundation.org>

[-- Attachment #1: Type: text/plain, Size: 2644 bytes --]

On Fri, 09 Oct 2009 01:07:49 PDT, akpm@linux-foundation.org said:
> The mm-of-the-moment snapshot 2009-10-09-01-07 has been uploaded to
> 
>    http://userweb.kernel.org/~akpm/mmotm/

Broke my iwl3945 wireless card:

Good (2.6.31-mmotm0917)
Oct  8 09:55:33 turing-police kernel: [    0.809101] iwl3945: Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux, 1.2.26ks
Oct  8 09:55:33 turing-police kernel: [    0.809106] iwl3945: Copyright(c) 2003-2009 Intel Corporation
Oct  8 09:55:33 turing-police kernel: [    0.809201] iwl3945 0000:0c:00.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
Oct  8 09:55:33 turing-police kernel: [    0.879463] iwl3945 0000:0c:00.0: Tunable channels: 11 802.11bg, 13 802.11a channels
Oct  8 09:55:33 turing-police kernel: [    0.879466] iwl3945 0000:0c:00.0: Detected Intel Wireless WiFi Link 3945ABG
...
Oct  8 09:55:35 turing-police kernel: [   31.599751] iwl3945 0000:0c:00.0: firmware: requesting iwlwifi-3945-2.ucode
Oct  8 09:55:35 turing-police kernel: [   31.697046] iwl3945 0000:0c:00.0: loaded firmware version 15.28.2.8
Oct  8 09:55:35 turing-police kernel: [   31.777214] Registered led device: iwl-phy0::radio
Oct  8 09:55:35 turing-police kernel: [   31.777430] Registered led device: iwl-phy0::assoc
Oct  8 09:55:35 turing-police kernel: [   31.777545] Registered led device: iwl-phy0::RX
Oct  8 09:55:35 turing-police kernel: [   31.777676] Registered led device: iwl-phy0::TX
Oct  8 09:55:35 turing-police kernel: [   31.789446] ADDRCONF(NETDEV_UP): wlan0: link is not ready
(and then wpa-supplicant is able to bring the card up when it finally gets launched by initscripts)

Bad 2.6.32-rc3-mmotm1009:

Oct  9 13:50:19 turing-police kernel: [    0.931788] iwl3945: Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux, 1.2.26ks
Oct  9 13:50:19 turing-police kernel: [    0.944678] iwl3945: Copyright(c) 2003-2009 Intel Corporation
Oct  9 13:50:19 turing-police kernel: [    0.957831] iwl3945 0000:0c:00.0: PCI INT A -> GSI 17 (level, low) -> IRQ 17
Oct  9 13:50:19 turing-police kernel: [    1.038946] iwl3945 0000:0c:00.0: Tunable channels: 11 802.11bg, 13 802.11a channels
Oct  9 13:50:19 turing-police kernel: [    1.038950] iwl3945 0000:0c:00.0: Detected Intel Wireless WiFi Link 3945ABG

We never see the firmware load request, and of course everything goes
pear-shaped after that doesn't happen....

Kernel is built with:

%  zgrep -i iwl /proc/config.gz 
CONFIG_IWLWIFI=y
CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT=y
# CONFIG_IWLWIFI_DEBUG is not set
CONFIG_IWLWIFI_DEVICE_TRACING=y
# CONFIG_IWLAGN is not set
CONFIG_IWL3945=y
CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y


[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply

* [PATCH -next] libertas: depends on CFG80211
From: Randy Dunlap @ 2009-10-09 23:17 UTC (permalink / raw)
  To: Stephen Rothwell, linux-wireless, Dan Williams
  Cc: linux-next, LKML, libertas-dev
In-Reply-To: <20091009190654.741eeffd.sfr@canb.auug.org.au>

From: Randy Dunlap <randy.dunlap@oracle.com>

libertas uses CFG80211 functions so it should depend on that symbol.

drivers/built-in.o: In function `lbs_cfg_free':
(.text+0x9ca93): undefined reference to `wiphy_unregister'
drivers/built-in.o: In function `lbs_cfg_free':
(.text+0x9ca9a): undefined reference to `wiphy_free'
drivers/built-in.o: In function `lbs_cfg_register':
(.text+0x9cb45): undefined reference to `wiphy_register'
drivers/built-in.o: In function `lbs_cfg_alloc':
(.text+0x9cc64): undefined reference to `wiphy_new'

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
---
 drivers/net/wireless/libertas/Kconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- linux-next-20091009.orig/drivers/net/wireless/libertas/Kconfig
+++ linux-next-20091009/drivers/net/wireless/libertas/Kconfig
@@ -1,6 +1,6 @@
 config LIBERTAS
 	tristate "Marvell 8xxx Libertas WLAN driver support"
-	depends on WLAN_80211
+	depends on WLAN_80211 && CFG80211
 	select WIRELESS_EXT
 	select WEXT_SPY
 	select LIB80211

^ permalink raw reply

* Re: mmotm 2009-10-09-01-07 uploaded (b43)
From: Randy Dunlap @ 2009-10-09 22:47 UTC (permalink / raw)
  To: akpm, linux-wireless; +Cc: linux-kernel
In-Reply-To: <200910090830.n998Ubvv020464@imap1.linux-foundation.org>

[-- Attachment #1: Type: text/plain, Size: 6339 bytes --]


In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/main.c:47:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
mmotm-2009-1009-0107/drivers/net/wireless/b43/main.c: In function 'b43_remove':
mmotm-2009-1009-0107/drivers/net/wireless/b43/main.c:5003: warning: passing argument 1 of 'b43_leds_unregister' from incompatible pointer type
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/tables.c:28:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/phy_common.c:34:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/phy_g.c:29:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/phy_a.c:29:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/phy_lp.c:26:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/tables_lpphy.c:26:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/sysfs.c:29:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/main.h:34,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/xmit.h:4,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/xmit.c:30:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/lo.c:30:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/wa.c:27:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/dma.c:30:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/pio.c:26:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want
In file included from mmotm-2009-1009-0107/drivers/net/wireless/b43/b43.h:12,
                 from mmotm-2009-1009-0107/drivers/net/wireless/b43/rfkill.c:25:
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: 'struct b43_wl' declared inside parameter list
mmotm-2009-1009-0107/drivers/net/wireless/b43/leds.h:79: warning: its scope is only this definition or declaration, which is probably not what you want



config attached.


---
~Randy

[-- Attachment #2: config-r2787 --]
[-- Type: application/octet-stream, Size: 40502 bytes --]

#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.32-rc3-mm1
# Fri Oct  9 10:26:10 2009
#
CONFIG_64BIT=y
# CONFIG_X86_32 is not set
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ZONE_DMA32=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_KTIME_SCALAR is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
# CONFIG_KERNEL_GZIP is not set
CONFIG_KERNEL_BZIP2=y
# CONFIG_KERNEL_LZMA is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_WATCH=y
CONFIG_AUDIT_TREE=y

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_TREE_PREEMPT_RCU is not set
# CONFIG_TINY_RCU is not set
# CONFIG_RCU_TRACE is not set
CONFIG_RCU_FANOUT=64
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
# CONFIG_IPC_NS is not set
CONFIG_USER_NS=y
# CONFIG_PID_NS is not set
CONFIG_NET_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
CONFIG_EVENT_PROFILE=y
# CONFIG_PERF_COUNTERS is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLQB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_TRACEPOINTS=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_API_DEBUG=y

#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
CONFIG_SLOW_WORK=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
# CONFIG_UTRACE is not set
CONFIG_BLOCK=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLOCK_COMPAT=y

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
# CONFIG_IOSCHED_CFQ is not set
CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
CONFIG_FREEZER=y

#
# Processor type and features
#
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_SMP is not set
CONFIG_X86_MPPARSE=y
# CONFIG_X86_EXTENDED_PLATFORM is not set
CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_PARAVIRT_GUEST=y
# CONFIG_XEN is not set
CONFIG_KVM_CLOCK=y
CONFIG_KVM_GUEST=y
CONFIG_PARAVIRT=y
CONFIG_PARAVIRT_CLOCK=y
# CONFIG_MEMTEST is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_CPU=y
CONFIG_X86_L1_CACHE_BYTES=64
CONFIG_X86_INTERNODE_CACHE_BYTES=64
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
# CONFIG_X86_DS is not set
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_DMI=y
CONFIG_SWIOTLB=y
CONFIG_IOMMU_HELPER=y
# CONFIG_IOMMU_API is not set
CONFIG_NR_CPUS=1
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
CONFIG_X86_MCE=y
CONFIG_X86_MCE_INTEL=y
# CONFIG_X86_MCE_AMD is not set
CONFIG_X86_MCE_THRESHOLD=y
# CONFIG_X86_MCE_INJECT is not set
CONFIG_X86_THERMAL_VECTOR=y
CONFIG_I8K=y
CONFIG_MICROCODE=y
# CONFIG_MICROCODE_INTEL is not set
CONFIG_MICROCODE_AMD=y
CONFIG_MICROCODE_OLD_INTERFACE=y
# CONFIG_X86_MSR is not set
CONFIG_X86_CPUID=y
CONFIG_X86_CPU_DEBUG=y
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_DIRECT_GBPAGES=y
CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
# CONFIG_SPARSEMEM_VMEMMAP is not set

#
# Memory hotplug is currently incompatible with Software Suspend
#
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
CONFIG_MEMORY_FAILURE=y
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
CONFIG_X86_RESERVE_LOW_64K=y
CONFIG_MTRR=y
CONFIG_MTRR_SANITIZER=y
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_SECCOMP=y
CONFIG_CC_STACKPROTECTOR_ALL=y
CONFIG_CC_STACKPROTECTOR=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
CONFIG_KEXEC_JUMP=y
CONFIG_PHYSICAL_START=0x1000000
CONFIG_RELOCATABLE=y
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_COMPAT_VDSO=y
# CONFIG_CMDLINE_BOOL is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y

#
# Power management and ACPI options
#
CONFIG_ARCH_HIBERNATION_HEADER=y
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_HIBERNATION_NVS=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""
# CONFIG_PM_RUNTIME is not set
CONFIG_SFI=y

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_DEBUG=y
# CONFIG_CPU_FREQ_STAT is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y

#
# CPUFreq processor drivers
#
# CONFIG_X86_P4_CLOCKMOD is not set

#
# shared options
#
# CONFIG_X86_SPEEDSTEP_LIB is not set
# CONFIG_CPU_IDLE is not set

#
# Memory power savings
#
CONFIG_I7300_IDLE_IOAT_CHANNEL=y
CONFIG_I7300_IDLE=y

#
# Bus options (PCI etc.)
#
# CONFIG_PCI is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_ISA_DMA_API=y
CONFIG_PCCARD=y
CONFIG_PCMCIA_DEBUG=y
CONFIG_PCMCIA=y
CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_PCMCIA_IOCTL=y

#
# PC-card bridges
#
CONFIG_VBUS_PROXY=y

#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
CONFIG_IA32_EMULATION=y
CONFIG_IA32_AOUT=y
CONFIG_COMPAT=y
CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_NET=y
CONFIG_COMPAT_NETLINK_MESSAGES=y

#
# Networking options
#
# CONFIG_PACKET is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_IPCOMP=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
# CONFIG_ASK_IP_FIB_HASH is not set
CONFIG_IP_FIB_TRIE=y
# CONFIG_IP_FIB_HASH is not set
CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
# CONFIG_IP_ROUTE_MULTIPATH is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
# CONFIG_NET_IPGRE is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
CONFIG_SYN_COOKIES=y
CONFIG_INET_AH=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_LRO=y
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=y
# CONFIG_INET6_ESP is not set
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_INET6_XFRM_TUNNEL=y
CONFIG_INET6_TUNNEL=y
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
# CONFIG_INET6_XFRM_MODE_BEET is not set
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y
# CONFIG_IPV6_SIT is not set
CONFIG_IPV6_TUNNEL=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
# CONFIG_IPV6_MROUTE is not set
CONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=y
# CONFIG_SCTP_DBG_MSG is not set
CONFIG_SCTP_DBG_OBJCNT=y
CONFIG_SCTP_HMAC_NONE=y
# CONFIG_SCTP_HMAC_SHA1 is not set
# CONFIG_SCTP_HMAC_MD5 is not set
CONFIG_RDS=y
CONFIG_RDS_TCP=y
CONFIG_RDS_DEBUG=y
# CONFIG_TIPC is not set
CONFIG_ATM=y
CONFIG_ATM_CLIP=y
# CONFIG_ATM_CLIP_NO_ICMP is not set
CONFIG_ATM_LANE=y
CONFIG_ATM_MPOA=y
# CONFIG_ATM_BR2684 is not set
CONFIG_STP=y
CONFIG_BRIDGE=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_TAG_DSA=y
CONFIG_NET_DSA_TAG_EDSA=y
# CONFIG_NET_DSA_TAG_TRAILER is not set
CONFIG_NET_DSA_MV88E6XXX=y
# CONFIG_NET_DSA_MV88E6060 is not set
CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
CONFIG_NET_DSA_MV88E6131=y
CONFIG_NET_DSA_MV88E6123_61_65=y
CONFIG_VLAN_8021Q=y
# CONFIG_VLAN_8021Q_GVRP is not set
CONFIG_DECNET=y
# CONFIG_DECNET_ROUTER is not set
CONFIG_LLC=y
CONFIG_LLC2=y
CONFIG_IPX=y
CONFIG_IPX_INTERN=y
CONFIG_ATALK=y
CONFIG_DEV_APPLETALK=y
CONFIG_IPDDP=y
# CONFIG_IPDDP_ENCAP is not set
CONFIG_IPDDP_DECAP=y
CONFIG_X25=y
CONFIG_LAPB=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
CONFIG_IEEE802154=y
CONFIG_NET_SCHED=y

#
# Queueing/Scheduling
#
CONFIG_NET_SCH_CBQ=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_HFSC=y
# CONFIG_NET_SCH_ATM is not set
# CONFIG_NET_SCH_PRIO is not set
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_RED=y
# CONFIG_NET_SCH_SFQ is not set
CONFIG_NET_SCH_TEQL=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_GRED=y
CONFIG_NET_SCH_DSMARK=y
# CONFIG_NET_SCH_NETEM is not set
CONFIG_NET_SCH_DRR=y
CONFIG_NET_SCH_INGRESS=y

#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_TCINDEX=y
CONFIG_NET_CLS_ROUTE4=y
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
# CONFIG_NET_CLS_RSVP is not set
CONFIG_NET_CLS_RSVP6=y
CONFIG_NET_CLS_FLOW=y
# CONFIG_NET_EMATCH is not set
CONFIG_NET_CLS_ACT=y
# CONFIG_NET_ACT_POLICE is not set
CONFIG_NET_ACT_GACT=y
# CONFIG_GACT_PROB is not set
# CONFIG_NET_ACT_MIRRED is not set
CONFIG_NET_ACT_NAT=y
CONFIG_NET_ACT_PEDIT=y
CONFIG_NET_ACT_SIMP=y
# CONFIG_NET_ACT_SKBEDIT is not set
CONFIG_NET_CLS_IND=y
CONFIG_NET_SCH_FIFO=y
# CONFIG_DCB is not set

#
# Network testing
#
CONFIG_NET_PKTGEN=y
CONFIG_NET_DROP_MONITOR=y
# CONFIG_HAMRADIO is not set
CONFIG_CAN=y
# CONFIG_CAN_RAW is not set
# CONFIG_CAN_BCM is not set

#
# CAN Device Drivers
#
CONFIG_CAN_VCAN=y
CONFIG_CAN_DEV=y
CONFIG_CAN_CALC_BITTIMING=y
# CONFIG_CAN_SJA1000 is not set
CONFIG_CAN_DEBUG_DEVICES=y
CONFIG_IRDA=y

#
# IrDA protocols
#
# CONFIG_IRLAN is not set
CONFIG_IRCOMM=y
# CONFIG_IRDA_ULTRA is not set

#
# IrDA options
#
# CONFIG_IRDA_CACHE_LAST_LSAP is not set
CONFIG_IRDA_FAST_RR=y
CONFIG_IRDA_DEBUG=y

#
# Infrared-port device drivers
#

#
# SIR device drivers
#
CONFIG_IRTTY_SIR=y

#
# Dongle support
#
CONFIG_DONGLE=y
CONFIG_ESI_DONGLE=y
CONFIG_ACTISYS_DONGLE=y
# CONFIG_TEKRAM_DONGLE is not set
CONFIG_TOIM3232_DONGLE=y
CONFIG_LITELINK_DONGLE=y
# CONFIG_MA600_DONGLE is not set
# CONFIG_GIRBIL_DONGLE is not set
# CONFIG_MCP2120_DONGLE is not set
CONFIG_OLD_BELKIN_DONGLE=y
CONFIG_ACT200L_DONGLE=y

#
# FIR device drivers
#
# CONFIG_NSC_FIR is not set
CONFIG_WINBOND_FIR=y
# CONFIG_SMC_IRCC_FIR is not set
# CONFIG_ALI_FIR is not set
CONFIG_VIA_FIR=y
# CONFIG_BT is not set
CONFIG_AF_RXRPC=y
CONFIG_AF_RXRPC_DEBUG=y
CONFIG_RXKAD=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_WIRELESS_EXT=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_WEXT_SPY=y
CONFIG_WEXT_PRIV=y
CONFIG_CFG80211=y
# CONFIG_NL80211_TESTMODE is not set
CONFIG_CFG80211_DEVELOPER_WARNINGS=y
CONFIG_CFG80211_REG_DEBUG=y
CONFIG_CFG80211_DEFAULT_PS_VALUE=1
CONFIG_CFG80211_DEFAULT_PS=y
# CONFIG_CFG80211_DEBUGFS is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_CFG80211_WEXT=y
# CONFIG_WIRELESS_EXT_SYSFS is not set
CONFIG_LIB80211=y
CONFIG_LIB80211_DEBUG=y
CONFIG_MAC80211=y
CONFIG_MAC80211_RC_MINSTREL=y
# CONFIG_MAC80211_RC_DEFAULT_PID is not set
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT="minstrel"
CONFIG_MAC80211_MESH=y
# CONFIG_MAC80211_LEDS is not set
CONFIG_MAC80211_DEBUGFS=y
CONFIG_MAC80211_DEBUG_MENU=y
CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT=y
# CONFIG_MAC80211_NOINLINE is not set
CONFIG_MAC80211_VERBOSE_DEBUG=y
# CONFIG_MAC80211_HT_DEBUG is not set
CONFIG_MAC80211_TKIP_DEBUG=y
# CONFIG_MAC80211_IBSS_DEBUG is not set
# CONFIG_MAC80211_VERBOSE_PS_DEBUG is not set
CONFIG_MAC80211_VERBOSE_MPL_DEBUG=y
CONFIG_MAC80211_DEBUG_COUNTERS=y
CONFIG_MAC80211_DRIVER_API_TRACER=y
# CONFIG_WIMAX is not set
CONFIG_RFKILL=y
CONFIG_RFKILL_LEDS=y
CONFIG_RFKILL_INPUT=y
CONFIG_NET_9P=y
CONFIG_NET_9P_DEBUG=y

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set
CONFIG_MISC_DEVICES=y
CONFIG_HWLAT_DETECTOR=y
# CONFIG_ENCLOSURE_SERVICES is not set
CONFIG_C2PORT=y
CONFIG_C2PORT_DURAMAR_2150=y

#
# EEPROM support
#
# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y

#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
CONFIG_IDE_XFER_MODE=y
CONFIG_IDE_TIMINGS=y
CONFIG_IDE_ATAPI=y
CONFIG_BLK_DEV_IDE_SATA=y
CONFIG_IDE_GD=y
# CONFIG_IDE_GD_ATA is not set
CONFIG_IDE_GD_ATAPI=y
CONFIG_BLK_DEV_IDECS=y
# CONFIG_BLK_DEV_IDECD is not set
CONFIG_BLK_DEV_IDETAPE=y
# CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_PROC_FS=y

#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_PLATFORM=y
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_CMD640_ENHANCED=y
# CONFIG_BLK_DEV_IDEDMA is not set

#
# SCSI device support
#
CONFIG_RAID_ATTRS=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_TGT=y
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
CONFIG_CHR_DEV_ST=y
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=y
# CONFIG_CHR_DEV_SCH is not set
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_FC_TGT_ATTRS is not set
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
# CONFIG_SCSI_SAS_LIBSAS is not set
CONFIG_SCSI_SRP_ATTRS=y
# CONFIG_SCSI_SRP_TGT_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=y
CONFIG_LIBFC=y
CONFIG_LIBFCOE=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
CONFIG_SCSI_DH=y
# CONFIG_SCSI_DH_RDAC is not set
CONFIG_SCSI_DH_HP_SW=y
CONFIG_SCSI_DH_EMC=y
CONFIG_SCSI_DH_ALUA=y
CONFIG_SCSI_OSD_INITIATOR=y
CONFIG_SCSI_OSD_ULD=y
CONFIG_SCSI_OSD_DPRINT_SENSE=1
# CONFIG_SCSI_OSD_DEBUG is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_ATA_VERBOSE_ERROR is not set
CONFIG_SATA_PMP=y
CONFIG_ATA_SFF=y
CONFIG_SATA_MV=y
CONFIG_PATA_PCMCIA=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
# CONFIG_MD_AUTODETECT is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_MD_RAID456=y
CONFIG_MD_RAID6_PQ=y
CONFIG_ASYNC_RAID6_TEST=y
CONFIG_MD_MULTIPATH=y
CONFIG_MD_FAULTY=y
CONFIG_BLK_DEV_DM=y
# CONFIG_DM_DEBUG is not set
CONFIG_DM_CRYPT=y
CONFIG_DM_SNAPSHOT=y
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_ZERO is not set
CONFIG_DM_MULTIPATH=y
# CONFIG_DM_MULTIPATH_QL is not set
# CONFIG_DM_MULTIPATH_ST is not set
CONFIG_DM_DELAY=y
CONFIG_DM_UEVENT=y
CONFIG_MACINTOSH_DRIVERS=y
# CONFIG_MAC_EMUMOUSEBTN is not set
CONFIG_NETDEVICES=y
# CONFIG_IFB is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
CONFIG_MACVLAN=y
CONFIG_EQUALIZER=y
CONFIG_TUN=y
# CONFIG_VETH is not set
CONFIG_PHYLIB=y

#
# MII PHY device drivers
#
CONFIG_MARVELL_PHY=y
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
CONFIG_CICADA_PHY=y
CONFIG_VITESSE_PHY=y
CONFIG_SMSC_PHY=y
CONFIG_BROADCOM_PHY=y
CONFIG_ICPLUS_PHY=y
CONFIG_REALTEK_PHY=y
# CONFIG_NATIONAL_PHY is not set
# CONFIG_STE10XP is not set
CONFIG_LSI_ET1011C_PHY=y
CONFIG_FIXED_PHY=y
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_ETHOC is not set
CONFIG_DNET=y
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
CONFIG_B44=y
CONFIG_KS8842=y
CONFIG_KS8851_MLL=y
CONFIG_NETDEV_1000=y
CONFIG_NETDEV_10000=y
CONFIG_WLAN=y
CONFIG_WLAN_PRE80211=y
# CONFIG_STRIP is not set
CONFIG_PCMCIA_WAVELAN=y
CONFIG_PCMCIA_NETWAVE=y
CONFIG_WLAN_80211=y
# CONFIG_PCMCIA_RAYCS is not set
CONFIG_LIBERTAS_THINFIRM=y
CONFIG_ATMEL=y
CONFIG_PCMCIA_ATMEL=y
CONFIG_AIRO_CS=y
CONFIG_PCMCIA_WL3501=y
CONFIG_MAC80211_HWSIM=y
CONFIG_ATH_COMMON=y
CONFIG_ATH_DEBUG=y
CONFIG_B43=y
CONFIG_B43_PCMCIA=y
# CONFIG_B43_SDIO is not set
CONFIG_B43_PIO=y
CONFIG_B43_PHY_LP=y
CONFIG_B43_HWRNG=y
# CONFIG_B43_DEBUG is not set
CONFIG_B43LEGACY=y
CONFIG_B43LEGACY_HWRNG=y
# CONFIG_B43LEGACY_DEBUG is not set
CONFIG_B43LEGACY_PIO=y
# CONFIG_B43LEGACY_DMA_AND_PIO_MODE is not set
# CONFIG_B43LEGACY_DMA_MODE is not set
CONFIG_B43LEGACY_PIO_MODE=y
# CONFIG_HOSTAP is not set
CONFIG_IWM=y
CONFIG_IWM_DEBUG=y
# CONFIG_LIBERTAS is not set
CONFIG_HERMES=y
CONFIG_HERMES_CACHE_FW_ON_INIT=y
CONFIG_PCMCIA_HERMES=y
CONFIG_PCMCIA_SPECTRUM=y
# CONFIG_P54_COMMON is not set
CONFIG_RT2X00=y
# CONFIG_WL12XX is not set

#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
CONFIG_NET_PCMCIA=y
CONFIG_PCMCIA_3C589=y
CONFIG_PCMCIA_3C574=y
CONFIG_PCMCIA_FMVJ18X=y
CONFIG_PCMCIA_PCNET=y
CONFIG_PCMCIA_NMCLAN=y
CONFIG_PCMCIA_SMC91C92=y
CONFIG_PCMCIA_XIRC2PS=y
CONFIG_PCMCIA_AXNET=y
# CONFIG_WAN is not set
# CONFIG_ATM_DRIVERS is not set
CONFIG_IEEE802154_DRIVERS=y
# CONFIG_IEEE802154_FAKEHARD is not set
# CONFIG_PPP is not set
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLHC=y
# CONFIG_SLIP_SMART is not set
# CONFIG_SLIP_MODE_SLIP6 is not set
CONFIG_NETCONSOLE=y
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETPOLL=y
CONFIG_NETPOLL_TRAP=y
CONFIG_NET_POLL_CONTROLLER=y
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
CONFIG_INPUT_POLLDEV=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
# CONFIG_INPUT_EVDEV is not set
CONFIG_INPUT_EVBUG=y

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_KEYBOARD_OPENCORES=y
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_KEYBOARD_SUNKBD=y
# CONFIG_KEYBOARD_XTKBD is not set
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_MOUSE_SERIAL=y
CONFIG_MOUSE_VSXXXAA=y
CONFIG_INPUT_JOYSTICK=y
CONFIG_JOYSTICK_ANALOG=y
CONFIG_JOYSTICK_A3D=y
CONFIG_JOYSTICK_ADI=y
CONFIG_JOYSTICK_COBRA=y
CONFIG_JOYSTICK_GF2K=y
CONFIG_JOYSTICK_GRIP=y
CONFIG_JOYSTICK_GRIP_MP=y
# CONFIG_JOYSTICK_GUILLEMOT is not set
CONFIG_JOYSTICK_INTERACT=y
CONFIG_JOYSTICK_SIDEWINDER=y
CONFIG_JOYSTICK_TMDC=y
# CONFIG_JOYSTICK_IFORCE is not set
# CONFIG_JOYSTICK_WARRIOR is not set
CONFIG_JOYSTICK_MAGELLAN=y
CONFIG_JOYSTICK_SPACEORB=y
CONFIG_JOYSTICK_SPACEBALL=y
# CONFIG_JOYSTICK_STINGER is not set
CONFIG_JOYSTICK_TWIDJOY=y
# CONFIG_JOYSTICK_ZHENHUA is not set
# CONFIG_JOYSTICK_JOYDUMP is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_AD7879 is not set
CONFIG_TOUCHSCREEN_FUJITSU=y
CONFIG_TOUCHSCREEN_GUNZE=y
# CONFIG_TOUCHSCREEN_ELO is not set
CONFIG_TOUCHSCREEN_WACOM_W8001=y
# CONFIG_TOUCHSCREEN_MTOUCH is not set
CONFIG_TOUCHSCREEN_INEXIO=y
# CONFIG_TOUCHSCREEN_MK712 is not set
CONFIG_TOUCHSCREEN_PENMOUNT=y
CONFIG_TOUCHSCREEN_TOUCHRIGHT=y
CONFIG_TOUCHSCREEN_TOUCHWIN=y
CONFIG_TOUCHSCREEN_TOUCHIT213=y
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_PCSPKR is not set
CONFIG_INPUT_UINPUT=y

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
CONFIG_SERIO_CT82C710=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=y
CONFIG_GAMEPORT=y
CONFIG_GAMEPORT_NS558=y
# CONFIG_GAMEPORT_L4 is not set

#
# Character devices
#
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_IPMI_HANDLER=y
CONFIG_IPMI_PANIC_EVENT=y
CONFIG_IPMI_PANIC_STRING=y
# CONFIG_IPMI_DEVICE_INTERFACE is not set
CONFIG_IPMI_SI=y
CONFIG_IPMI_WATCHDOG=y
CONFIG_IPMI_POWEROFF=y
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
CONFIG_HW_RANDOM_VIA=y
CONFIG_NVRAM=y
CONFIG_RTC=y
# CONFIG_R3964 is not set

#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
CONFIG_CARDMAN_4000=y
# CONFIG_CARDMAN_4040 is not set
# CONFIG_IPWIRELESS is not set
CONFIG_MWAVE=y
CONFIG_PC8736x_GPIO=y
CONFIG_NSC_GPIO=y
# CONFIG_RAW_DRIVER is not set
CONFIG_HANGCHECK_TIMER=y
CONFIG_TCG_TPM=y
# CONFIG_TCG_NSC is not set
# CONFIG_TCG_ATMEL is not set
# CONFIG_TELCLOCK is not set
# CONFIG_UMMUNOTIFY is not set
# CONFIG_I2C is not set
# CONFIG_SPI is not set

#
# PPS support
#
# CONFIG_PPS is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
CONFIG_W1=y

#
# 1-wire Bus Masters
#

#
# 1-wire Slaves
#
CONFIG_W1_SLAVE_THERM=y
CONFIG_W1_SLAVE_SMEM=y
CONFIG_W1_SLAVE_DS2431=y
# CONFIG_W1_SLAVE_DS2433 is not set
CONFIG_W1_SLAVE_DS2760=y
# CONFIG_W1_SLAVE_BQ27000 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
CONFIG_HWMON_DEBUG_CHIP=y

#
# Native drivers
#
# CONFIG_SENSORS_ABITUGURU is not set
CONFIG_SENSORS_ABITUGURU3=y
# CONFIG_SENSORS_F71805F is not set
CONFIG_SENSORS_F71882FG=y
CONFIG_SENSORS_CORETEMP=y
# CONFIG_SENSORS_IBMAEM is not set
CONFIG_SENSORS_IBMPEX=y
# CONFIG_SENSORS_IT87 is not set
CONFIG_SENSORS_PC87360=y
CONFIG_SENSORS_PC87427=y
# CONFIG_SENSORS_SMSC47M1 is not set
CONFIG_SENSORS_SMSC47B397=y
CONFIG_SENSORS_VT1211=y
# CONFIG_SENSORS_W83627HF is not set
CONFIG_SENSORS_W83627EHF=y
CONFIG_SENSORS_HDAPS=y
CONFIG_SENSORS_APPLESMC=y
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
CONFIG_SSB=y
CONFIG_SSB_SPROM=y
CONFIG_SSB_BLOCKIO=y
CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
CONFIG_SSB_PCMCIAHOST=y
CONFIG_SSB_SDIOHOST_POSSIBLE=y
# CONFIG_SSB_SDIOHOST is not set
# CONFIG_SSB_DEBUG is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
CONFIG_MFD_SM501=y
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_REGULATOR is not set
CONFIG_MEDIA_SUPPORT=y

#
# Multimedia core support
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
# CONFIG_VIDEO_MEDIA is not set

#
# Multimedia drivers
#
# CONFIG_DAB is not set

#
# Graphics support
#
CONFIG_VGASTATE=y
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
CONFIG_FB_BOOT_VESA_SUPPORT=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
# CONFIG_FB_FOREIGN_ENDIAN is not set
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set

#
# Frame buffer hardware drivers
#
CONFIG_FB_ARC=y
CONFIG_FB_VGA16=y
CONFIG_FB_VESA=y
# CONFIG_FB_N411 is not set
CONFIG_FB_HGA=y
CONFIG_FB_HGA_ACCEL=y
CONFIG_FB_S1D13XXX=y
CONFIG_FB_SM501=y
CONFIG_FB_VIRTUAL=y
CONFIG_FB_METRONOME=y
CONFIG_FB_MB862XX=y
# CONFIG_FB_BROADSHEET is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_MBP_NVIDIA=y
CONFIG_BACKLIGHT_SAHARA=y

#
# Display device support
#
CONFIG_DISPLAY_SUPPORT=y

#
# Display hardware drivers
#

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
# CONFIG_LOGO is not set
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
CONFIG_SND_HWDEP=y
# CONFIG_SND_SEQUENCER is not set
# CONFIG_SND_MIXER_OSS is not set
# CONFIG_SND_PCM_OSS is not set
# CONFIG_SND_RTCTIMER is not set
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_VERBOSE_PROCFS is not set
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_VERBOSE=y
CONFIG_SND_DMA_SGBUF=y
# CONFIG_SND_RAWMIDI_SEQ is not set
# CONFIG_SND_OPL3_LIB_SEQ is not set
# CONFIG_SND_OPL4_LIB_SEQ is not set
# CONFIG_SND_SBAWE_SEQ is not set
# CONFIG_SND_EMU10K1_SEQ is not set
CONFIG_SND_VX_LIB=y
# CONFIG_SND_DRIVERS is not set
CONFIG_SND_PCMCIA=y
CONFIG_SND_VXPOCKET=y
CONFIG_SND_PDAUDIOCF=y
# CONFIG_SND_SOC is not set
CONFIG_SOUND_PRIME=y
# CONFIG_SOUND_OSS is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HIDRAW is not set
# CONFIG_HID_PID is not set

#
# Special HID drivers
#
# CONFIG_USB_SUPPORT is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set

#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_SDIO_UART=y
CONFIG_MMC_TEST=y

#
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_SDHCI is not set
CONFIG_MMC_WBSD=y
# CONFIG_MMC_AT91 is not set
# CONFIG_MMC_ATMELMCI is not set
CONFIG_MEMSTICK=y
CONFIG_MEMSTICK_DEBUG=y

#
# MemoryStick drivers
#
# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
CONFIG_MSPRO_BLOCK=y

#
# MemoryStick Host Controller Drivers
#
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y

#
# LED drivers
#
CONFIG_LEDS_ALIX2=y
CONFIG_LEDS_CLEVO_MAIL=y

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y

#
# iptables trigger is under Netfilter config (LED target)
#
# CONFIG_ACCESSIBILITY is not set
CONFIG_EDAC=y

#
# Reporting subsystems
#
CONFIG_EDAC_DEBUG=y
CONFIG_EDAC_DEBUG_VERBOSE=y
# CONFIG_EDAC_MM_EDAC is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
CONFIG_AUXDISPLAY=y
CONFIG_UIO=y
CONFIG_UIO_PDRV=y
CONFIG_UIO_PDRV_GENIRQ=y
CONFIG_UIO_SMX=y
# CONFIG_UIO_SERCOS3 is not set

#
# TI VLYNQ
#
CONFIG_STAGING=y
CONFIG_STAGING_EXCLUDE_BUILD=y
# CONFIG_X86_PLATFORM_DEVICES is not set

#
# Firmware Drivers
#
CONFIG_EDD=y
CONFIG_EDD_OFF=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DELL_RBU=y
CONFIG_DCDBAS=y
# CONFIG_DMIID is not set
CONFIG_ISCSI_IBFT_FIND=y
CONFIG_ISCSI_IBFT=y

#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT2_FS_XIP=y
CONFIG_EXT3_FS=y
CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_EXT4_FS=y
# CONFIG_EXT4_FS_XATTR is not set
# CONFIG_EXT4_DEBUG is not set
CONFIG_FS_XIP=y
CONFIG_JBD=y
CONFIG_JBD_DEBUG=y
CONFIG_JBD2=y
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
CONFIG_REISERFS_CHECK=y
# CONFIG_REISERFS_PROC_INFO is not set
CONFIG_REISERFS_FS_XATTR=y
CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=y
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
# CONFIG_XFS_DEBUG is not set
CONFIG_GFS2_FS=y
# CONFIG_GFS2_FS_LOCKING_DLM is not set
CONFIG_OCFS2_FS=y
# CONFIG_OCFS2_FS_O2CB is not set
# CONFIG_OCFS2_FS_STATS is not set
CONFIG_OCFS2_DEBUG_MASKLOG=y
CONFIG_OCFS2_DEBUG_FS=y
CONFIG_OCFS2_FS_POSIX_ACL=y
CONFIG_BTRFS_FS=y
# CONFIG_BTRFS_FS_POSIX_ACL is not set
CONFIG_NILFS2_FS=y
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_PRINT_QUOTA_WARNING=y
CONFIG_QUOTA_TREE=y
CONFIG_QFMT_V1=y
# CONFIG_QFMT_V2 is not set
CONFIG_QUOTACTL=y
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set

#
# Caches
#
CONFIG_FSCACHE=y
# CONFIG_FSCACHE_STATS is not set
CONFIG_FSCACHE_HISTOGRAM=y
CONFIG_FSCACHE_DEBUG=y
CONFIG_CACHEFILES=y
CONFIG_CACHEFILES_DEBUG=y
CONFIG_CACHEFILES_HISTOGRAM=y

#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
CONFIG_UDF_FS=y
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
CONFIG_NTFS_DEBUG=y
CONFIG_NTFS_RW=y

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_EXPORTFS=y

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
CONFIG_OSF_PARTITION=y
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
# CONFIG_MINIX_SUBPARTITION is not set
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_LDM_PARTITION=y
CONFIG_LDM_DEBUG=y
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_SYSV68_PARTITION=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
# CONFIG_NLS_CODEPAGE_852 is not set
CONFIG_NLS_CODEPAGE_855=y
# CONFIG_NLS_CODEPAGE_857 is not set
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
CONFIG_NLS_CODEPAGE_862=y
CONFIG_NLS_CODEPAGE_863=y
CONFIG_NLS_CODEPAGE_864=y
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_869=y
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
CONFIG_NLS_CODEPAGE_874=y
# CONFIG_NLS_ISO8859_8 is not set
CONFIG_NLS_CODEPAGE_1250=y
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_ISO8859_3=y
CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
CONFIG_NLS_ISO8859_13=y
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=y
# CONFIG_DLM is not set

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
# CONFIG_DEBUG_KERNEL is not set
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
CONFIG_SLUB_DEBUG_ON=y
# CONFIG_SLUB_STATS is not set
CONFIG_TRACE_IRQFLAGS=y
CONFIG_STACKTRACE=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
CONFIG_RCU_CPU_STALL_DETECTOR=y
CONFIG_LATENCYTOP=y
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SYSPROF_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_BOOT_TRACER=y
CONFIG_TRACE_BRANCH_PROFILING=y
# CONFIG_BRANCH_PROFILE_NONE is not set
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
CONFIG_PROFILE_ALL_BRANCHES=y
# CONFIG_BRANCH_TRACER is not set
CONFIG_POWER_TRACER=y
CONFIG_STACK_TRACER=y
CONFIG_KMEMTRACE=y
CONFIG_WORKQUEUE_TRACER=y
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_FTRACE is not set
CONFIG_FUNCTION_PROFILER=y
CONFIG_FTRACE_SELFTEST=y
CONFIG_FTRACE_STARTUP_TEST=y
# CONFIG_EVENT_TRACE_TEST_SYSCALLS is not set
CONFIG_RING_BUFFER_BENCHMARK=y
CONFIG_BUILD_DOCSRC=y
CONFIG_DYNAMIC_DEBUG=y
# CONFIG_DMA_API_DEBUG is not set
CONFIG_SAMPLES=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_KMEMCHECK=y
CONFIG_STRICT_DEVMEM=y
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
CONFIG_IOMMU_STRESS=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
CONFIG_IO_DELAY_0XED=y
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=1
CONFIG_OPTIMIZE_INLINING=y

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
CONFIG_SECURITYFS=y
CONFIG_SECURITY_FILE_CAPABILITIES=y
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
CONFIG_ASYNC_PQ=y
CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
# CONFIG_CRYPTO_AUTHENC is not set

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
CONFIG_CRYPTO_SEQIV=y

#
# Block modes
#
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_ECB=y
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_PCBC=y
# CONFIG_CRYPTO_XTS is not set
CONFIG_CRYPTO_FPU=y

#
# Hash modes
#
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_VMAC=y

#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32C_INTEL=y
# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_RMD128=y
CONFIG_CRYPTO_RMD160=y
CONFIG_CRYPTO_RMD256=y
CONFIG_CRYPTO_RMD320=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_TGR192=y
CONFIG_CRYPTO_WP512=y

#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_X86_64=y
CONFIG_CRYPTO_AES_NI_INTEL=y
CONFIG_CRYPTO_ANUBIS=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_CAMELLIA=y
# CONFIG_CRYPTO_CAST5 is not set
CONFIG_CRYPTO_CAST6=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_FCRYPT=y
CONFIG_CRYPTO_KHAZAD=y
CONFIG_CRYPTO_SALSA20=y
CONFIG_CRYPTO_SALSA20_X86_64=y
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
CONFIG_CRYPTO_TEA=y
# CONFIG_CRYPTO_TWOFISH is not set
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CRYPTO_TWOFISH_X86_64=y

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_ZLIB=y
CONFIG_CRYPTO_LZO=y

#
# Random Number Generation
#
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_PADLOCK=y
# CONFIG_CRYPTO_DEV_PADLOCK_AES is not set
CONFIG_CRYPTO_DEV_PADLOCK_SHA=y
CONFIG_HAVE_KVM=y
# CONFIG_VIRTUALIZATION is not set
CONFIG_BINARY_PRINTF=y

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_NLATTR=y
CONFIG_SHM_SIGNAL=y
CONFIG_IOQ=y

^ permalink raw reply

* Re: pull request: wireless-next-2.6 2009-10-09
From: David Miller @ 2009-10-09 21:40 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev
In-Reply-To: <20091009210555.GC22861@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Fri, 9 Oct 2009 17:05:55 -0400

> Here is the usual big first post-window pull request for -next...
> Mostly it is the usual suspects, lots of iwlwifi and ath* along
> with a smattering of other bits.  There are even a few from me! :-)
> Most of these have spent several days banging-around in -next (which
> helped to find some Kconfig problems).
> 
> Please let me know if there are problems!

Pulled, thanks a lot John!

^ permalink raw reply

* pull request: wireless-next-2.6 2009-10-09
From: John W. Linville @ 2009-10-09 21:05 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev

Dave,

Here is the usual big first post-window pull request for -next...
Mostly it is the usual suspects, lots of iwlwifi and ath* along
with a smattering of other bits.  There are even a few from me! :-)
Most of these have spent several days banging-around in -next (which
helped to find some Kconfig problems).

Please let me know if there are problems!

Thanks,

John

---

Individual patches are available here:

	http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6/

---

The following changes since commit d519e17e2d01a0ee9abe083019532061b4438065:
  Andy Gospodarek (1):
        net: export device speed and duplex via sysfs

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git master

Abhijeet Kolekar (2):
      iwlwifi/iwl3945 : unify apm stop operation
      iwlwifi: replace iwl_poll_direct_bit with iwl_poll_bit for CSR access

Amitkumar Karwar (2):
      libertas: Add auto deep sleep support for SD8385/SD8686/SD8688
      libertas: Use lbs_is_cmd_allowed() check in command handling routines.

Christian Lamparter (1):
      iwlwifi: drop lib80211 dependency

Daniel C Halperin (3):
      iwlwifi: clean up rs_tx_status
      iwlwifi: do not clear TX info flags when receiving BlockAckResponse
      iwlwifi: add aggregation tables to the rate scaling algorithm

Holger Schurig (5):
      nl80211: report age of scan results
      libertas: separate libertas' Kconfig in it's own file
      libertas: first stab at cfg80211 support
      libertas: remove extraneous select FW_LOADER
      libertas: depend on CONFIG_CFG80211

Huaxu Wan (2):
      iwlwifi: add module firmware info for 1000 series
      iwlwifi: clear the translate table area

Jaswinder Singh Rajput (1):
      b43: Comment unused functions lpphy_restore_dig_flt_state and lpphy_disable_rx_gain_override

Joerg Albert (3):
      ar9170: fixed coding style, moved define
      ar9170: add heavy clip handling
      ar9170: handle overflow in tsf_low register during get_tsf

Johannes Berg (10):
      iwlwifi: clean up ht config a little
      iwlwifi: clean up ht config naming
      iwlwifi: clarify and clean up chain settings
      iwlwifi: fix a typo
      iwlwifi: default to using all chains
      iwlwifi: support idle for 6000 series hw
      wext: refactor
      iwlwifi: device tracing
      iwlwifi: LED cleanup
      wireless: make wireless drivers select core

John W. Linville (6):
      wireless: implement basic ethtool support for cfg80211 devices
      mac80211: support ETHTOOL_GPERMADDR
      iwmc3200wifi: support ETHTOOL_GPERMADDR
      ipw2200: support ETHTOOL_GPERMADDR
      orinoco: support ETHTOOL_GPERMADDR
      net/wireless/ethtool.h: drop unnecessary include of linux/ethtool.h

Kalle Valo (3):
      wl1251: remove wl1251_netlink.h
      cfg80211: add firmware and hardware version to wiphy
      at76c50x-usb: set firmware and hardware version in wiphy

Larry Finger (1):
      staging: Add proper selection of WIRELESS_EXT and WEXT_PRIV

Luis R. Rodriguez (68):
      ath9k: use ath_hw for DPRINTF() and debug init/exit
      ath9k: move btcoex core driver info to its own struct
      ath9k: move hw specific btcoex info to ath_hw
      ath9k: split bluetooth hardware coex init into two helpers
      ath9k: move driver core helpers to main.c
      ath9k: split ath9k_hw_btcoex_enable() into two helpers
      ath9k: replaces SC_OP_BTCOEX_ENABLED with a bool
      ath9k: move bt_stomp_type to driver core
      ath9k: remove unused bt_duty_cycle
      ath9k: rename btcoex_scheme to just scheme
      ath9k: rename ath_btcoex_info to ath_btcoex_hw
      ath9k: simplify ath_btcoex_bt_stomp()
      ath9k: now move ath9k_hw_btcoex_set_weight() to btcoex.c
      ath9k: move ath_btcoex_config and ath_bt_mode to btcoex.c
      ath9k: rename ath_btcoex_supported() to ath9k_hw_btcoex_supported()
      ath9k: move ps helpers onto core driver when reseting tsf
      ath9k: move ath9k_ps_wakeup() and ath9k_ps_restore() to main.c
      ath9k: avoid usage of ath9k_hw_setpower() on hw.c
      ath9k: move ath9k_hw_setpower() to main.c
      ath9k: rename driver core and hw power save helpers
      ath: move ath_bcast_mac to common header
      atheros: use get_unaligned_le*() for bssid mask setting
      ath9k: make ath9k_hw_setbssidmask() and ath9k_hw_write_associd() use ath_hw
      ath9k: Use ath9k_hw_setbssidmask() on reset
      ath9k: use ath9k_hw_write_associd() on reset
      atheros/ath9k: move macaddr, curaid, curbssid and bssidmask to common
      ar9170: make use of common macaddr and curbssid
      ath5k: use common curbssid, bssidmask and macaddr
      ath5k: initialize eeprom struct early on attach
      ath9k: move ath_common to ath_hw
      ath5k: move ath_common to ath5k_hw
      ath9k: Define bus agnostic bluetooth coex prep helper
      atheros/ath9k: add common read/write ops and port ath9k to use it
      ath5k: allocate ath5k_hw prior to initializing hw
      ath5k: define ath_common ops
      atheros: define shared bssidmask setting
      atheros: add ieee80211_hw to ath_common
      ath9k: separate core driver and hw timer code
      atheros: add common debug printing
      atheros: move tx/rx chainmask to ath_common
      ath9k: remove ath9k 25 MHz HT40 spacing stuff
      ath9k: remove ath9k_ht_macmode
      ath9k: move ATH_AMPDU_LIMIT_MAX to hw.h
      ath9k: remove driver ASSERT, just use BUG_ON()
      ath9k: clarify what hw code is and remove ath9k.h from a few files
      ath9k: move ATH9K_RSSI_BAD to hw.h
      atheros: move bus ops to ath_common
      ath9k: make ath9k_common_ops const
      ath9k: use common read/write ops on pci and debug code
      ath9k: move hw code to its own module
      ath9k_hw: print device ID if not supported
      ath9k_hw: add AR9271 srev and device ID to allow hw to support ar9271
      atheros: define a common priv struct
      ath5k: fix regression on setting bssid mask on association
      ath5k: use ath_hw_setbssidmask() for bssid mask setting upon assoc
      ath5k: fix regression introduced upon the removal of AR5K_HIGH_ID()
      ath5k: simplify passed params to ath5k_hw_set_associd()
      ath5k: remove temporary low_id and high_id vars on ath5k_hw_set_associd()
      ath5k: fix regression which triggers an SME join upon assoc
      ath5k: enable Power-Save Polls by setting the association ID
      ath9k: move common->debug_mask setting to ath_init_softc()
      ath9k: initialize hw prior to debugfs
      ath9k: add helper to un-init the hw properly
      ath9k: add a helper to clean the core driver upon module unload
      ath9k: move ath_cleanup() below helpers to avoid forward declarations
      ath9k: rename ath_beaconq_setup() to ath9k_hw_beaconq_setup()
      ath9k: use right parameter for MODULE_PARM_DESC() for debug
      libertas: remove double assignment of dev->netdev_ops

Rafael J. Wysocki (1):
      Wireless / ath5k: Simplify suspend and resume callbacks

Randy Dunlap (1):
      wireless: fix CFG80211_WEXT build problems

Senthil Balasubramanian (5):
      ath9k: Allow PSPOLL only when the interface is configured in AP mode
      ath9k: Handle ATH9K_BEACON_RESET_TSF properly
      ath9k: Reduce PLL Settle time and eliminate redundant PLL calls.
      ath9k: Advertise midband for AR5416 devices
      ath9k: Fix bugs in handling TX power

Sujith (2):
      ath9k: Update INI release for AR9287
      ath9k: Fix RTC reset for AR5416

Vasanthakumar Thiagarajan (1):
      ath9k: Update initvals

Vivek Natarajan (1):
      ath9k: Add Calibration checks

Wey-Yi Guy (19):
      iwlwifi: modify LED blink index table
      iwlwifi: remove un-supported eeprom parameters
      iwlwifi: separate nic_config for different NIC
      iwlwifi: separate set_hw_params function for 6000 series
      iwlwifi: Adjust blink rate to compensate Clock difference
      iwlwifi: show NVM version in debugfs
      iwlwifi: Use RTS/CTS as the preferred protection mechanism for 6000 series
      iwlwifi: allow user change protection mechanism for HT
      iwlwifi: EEPROM version for 1000 and 6000 series
      iwlwifi: use S_IRUGO and S_IWUSR in module parameters
      iwlwifi: send cmd to uCode to configure valid tx antenna
      iwlwifi: update PCI Subsystem ID for 1000 series
      iwlwifi: update PCI Subsystem ID for 6000 series
      iwlwifi: add LED mode to support different LED behavior
      iwlwifi: Chain Noise Calibration for 6000 series
      iwlwifi: reliable entering of critical temperature state
      iwlwifi: change valid EEPROM version for 1000 series
      iwlwifi: set default aggregation frame count limit to 31
      iwlwifi: validate the signature for EEPROM and OTP

 drivers/net/wireless/Kconfig                 |   84 +-
 drivers/net/wireless/at76c50x-usb.c          |   10 +
 drivers/net/wireless/ath/Kconfig             |    8 +
 drivers/net/wireless/ath/Makefile            |    9 +-
 drivers/net/wireless/ath/ar9170/ar9170.h     |    4 +-
 drivers/net/wireless/ath/ar9170/cmd.c        |    3 +-
 drivers/net/wireless/ath/ar9170/cmd.h        |    1 +
 drivers/net/wireless/ath/ar9170/hw.h         |    2 +
 drivers/net/wireless/ath/ar9170/mac.c        |   15 +-
 drivers/net/wireless/ath/ar9170/main.c       |   30 +-
 drivers/net/wireless/ath/ar9170/phy.c        |   99 ++-
 drivers/net/wireless/ath/ath.h               |   41 +
 drivers/net/wireless/ath/ath5k/ath5k.h       |   40 +-
 drivers/net/wireless/ath/ath5k/attach.c      |   31 +-
 drivers/net/wireless/ath/ath5k/base.c        |  116 ++-
 drivers/net/wireless/ath/ath5k/base.h        |   12 -
 drivers/net/wireless/ath/ath5k/initvals.c    |    4 +-
 drivers/net/wireless/ath/ath5k/pcu.c         |  193 +---
 drivers/net/wireless/ath/ath5k/reg.h         |    8 +-
 drivers/net/wireless/ath/ath5k/reset.c       |   16 +-
 drivers/net/wireless/ath/ath9k/Kconfig       |    8 +
 drivers/net/wireless/ath/ath9k/Makefile      |   27 +-
 drivers/net/wireless/ath/ath9k/ahb.c         |   19 +-
 drivers/net/wireless/ath/ath9k/ani.c         |  141 ++-
 drivers/net/wireless/ath/ath9k/ath9k.h       |   73 +-
 drivers/net/wireless/ath/ath9k/beacon.c      |  112 +-
 drivers/net/wireless/ath/ath9k/btcoex.c      |  383 ++----
 drivers/net/wireless/ath/ath9k/btcoex.h      |   64 +-
 drivers/net/wireless/ath/ath9k/calib.c       |  391 ++++---
 drivers/net/wireless/ath/ath9k/calib.h       |    2 +
 drivers/net/wireless/ath/ath9k/debug.c       |   55 +-
 drivers/net/wireless/ath/ath9k/debug.h       |   36 +-
 drivers/net/wireless/ath/ath9k/eeprom.c      |    8 +-
 drivers/net/wireless/ath/ath9k/eeprom.h      |    9 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c   |   90 +-
 drivers/net/wireless/ath/ath9k/eeprom_9287.c |   97 +-
 drivers/net/wireless/ath/ath9k/eeprom_def.c  |  183 ++-
 drivers/net/wireless/ath/ath9k/hw.c          |  595 +++++-----
 drivers/net/wireless/ath/ath9k/hw.h          |   63 +-
 drivers/net/wireless/ath/ath9k/initvals.h    |   72 +-
 drivers/net/wireless/ath/ath9k/mac.c         |  162 ++-
 drivers/net/wireless/ath/ath9k/mac.h         |   11 +-
 drivers/net/wireless/ath/ath9k/main.c        |  841 +++++++++----
 drivers/net/wireless/ath/ath9k/pci.c         |   37 +-
 drivers/net/wireless/ath/ath9k/phy.c         |   50 +-
 drivers/net/wireless/ath/ath9k/phy.h         |    1 +
 drivers/net/wireless/ath/ath9k/rc.c          |   33 +-
 drivers/net/wireless/ath/ath9k/recv.c        |   62 +-
 drivers/net/wireless/ath/ath9k/reg.h         |    5 +-
 drivers/net/wireless/ath/ath9k/virtual.c     |   22 +-
 drivers/net/wireless/ath/ath9k/xmit.c        |  113 +-
 drivers/net/wireless/ath/debug.c             |   32 +
 drivers/net/wireless/ath/debug.h             |   77 ++
 drivers/net/wireless/ath/hw.c                |  126 ++
 drivers/net/wireless/ath/reg.h               |   27 +
 drivers/net/wireless/b43/phy_lp.c            |    6 +
 drivers/net/wireless/hostap/Kconfig          |    2 +
 drivers/net/wireless/ipw2x00/Kconfig         |    7 +-
 drivers/net/wireless/ipw2x00/ipw2200.c       |    1 +
 drivers/net/wireless/iwlwifi/Kconfig         |   28 +-
 drivers/net/wireless/iwlwifi/Makefile        |   12 +-
 drivers/net/wireless/iwlwifi/iwl-1000.c      |   35 +-
 drivers/net/wireless/iwlwifi/iwl-3945-led.c  |  371 +-----
 drivers/net/wireless/iwlwifi/iwl-3945-led.h  |   22 +-
 drivers/net/wireless/iwlwifi/iwl-3945.c      |   65 +-
 drivers/net/wireless/iwlwifi/iwl-3945.h      |    2 +-
 drivers/net/wireless/iwlwifi/iwl-4965.c      |   71 +-
 drivers/net/wireless/iwlwifi/iwl-5000.c      |  127 +-
 drivers/net/wireless/iwlwifi/iwl-6000.c      |  245 ++++-
 drivers/net/wireless/iwlwifi/iwl-agn-led.c   |   85 ++
 drivers/net/wireless/iwlwifi/iwl-agn-led.h   |   32 +
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c    |  466 ++++----
 drivers/net/wireless/iwlwifi/iwl-agn.c       |  124 ++-
 drivers/net/wireless/iwlwifi/iwl-calib.c     |   66 +-
 drivers/net/wireless/iwlwifi/iwl-commands.h  |   12 +-
 drivers/net/wireless/iwlwifi/iwl-core.c      |  209 ++--
 drivers/net/wireless/iwlwifi/iwl-core.h      |   31 +-
 drivers/net/wireless/iwlwifi/iwl-csr.h       |    7 +-
 drivers/net/wireless/iwlwifi/iwl-debug.h     |    2 -
 drivers/net/wireless/iwlwifi/iwl-debugfs.c   |   17 +-
 drivers/net/wireless/iwlwifi/iwl-dev.h       |   31 +-
 drivers/net/wireless/iwlwifi/iwl-devtrace.c  |   13 +
 drivers/net/wireless/iwlwifi/iwl-devtrace.h  |  178 +++
 drivers/net/wireless/iwlwifi/iwl-eeprom.c    |   45 +-
 drivers/net/wireless/iwlwifi/iwl-eeprom.h    |   17 +-
 drivers/net/wireless/iwlwifi/iwl-io.h        |   16 +-
 drivers/net/wireless/iwlwifi/iwl-led.c       |  323 +----
 drivers/net/wireless/iwlwifi/iwl-led.h       |   46 +-
 drivers/net/wireless/iwlwifi/iwl-power.c     |  149 ++-
 drivers/net/wireless/iwlwifi/iwl-power.h     |    3 +
 drivers/net/wireless/iwlwifi/iwl-scan.c      |    1 -
 drivers/net/wireless/iwlwifi/iwl-tx.c        |   26 +-
 drivers/net/wireless/iwlwifi/iwl3945-base.c  |   28 +-
 drivers/net/wireless/iwmc3200wifi/main.c     |    2 +
 drivers/net/wireless/libertas/Kconfig        |   39 +
 drivers/net/wireless/libertas/Makefile       |   15 +-
 drivers/net/wireless/libertas/README         |   26 +-
 drivers/net/wireless/libertas/cfg.c          |  198 +++
 drivers/net/wireless/libertas/cfg.h          |   16 +
 drivers/net/wireless/libertas/cmd.c          |  106 ++-
 drivers/net/wireless/libertas/cmdresp.c      |   12 +
 drivers/net/wireless/libertas/decl.h         |    3 +
 drivers/net/wireless/libertas/defs.h         |    2 +
 drivers/net/wireless/libertas/dev.h          |   19 +
 drivers/net/wireless/libertas/host.h         |    1 +
 drivers/net/wireless/libertas/if_cs.c        |    3 +
 drivers/net/wireless/libertas/if_sdio.c      |   56 +
 drivers/net/wireless/libertas/if_sdio.h      |    3 +-
 drivers/net/wireless/libertas/if_spi.c       |    3 +
 drivers/net/wireless/libertas/if_usb.c       |    3 +
 drivers/net/wireless/libertas/main.c         |  171 ++-
 drivers/net/wireless/libertas/wext.c         |   54 +-
 drivers/net/wireless/orinoco/Kconfig         |    4 +-
 drivers/net/wireless/orinoco/main.c          |    1 +
 drivers/net/wireless/wl12xx/wl1251_netlink.h |   30 -
 drivers/staging/rtl8187se/Kconfig            |    3 +-
 drivers/staging/rtl8192e/Kconfig             |    3 +-
 drivers/staging/vt6655/Kconfig               |    4 +-
 drivers/staging/vt6656/Kconfig               |    4 +-
 include/linux/nl80211.h                      |    2 +
 include/net/cfg80211.h                       |    9 +-
 include/net/iw_handler.h                     |   14 +-
 include/net/net_namespace.h                  |    2 +-
 include/net/wext.h                           |   49 +-
 net/core/net-sysfs.c                         |    6 +-
 net/mac80211/iface.c                         |    5 +-
 net/socket.c                                 |    4 +-
 net/wireless/Kconfig                         |   50 +-
 net/wireless/Makefile                        |   10 +-
 net/wireless/core.c                          |   17 +-
 net/wireless/ethtool.c                       |   45 +
 net/wireless/ethtool.h                       |    6 +
 net/wireless/ibss.c                          |   10 +-
 net/wireless/mlme.c                          |    2 +-
 net/wireless/nl80211.c                       |    6 +-
 net/wireless/scan.c                          |    6 +-
 net/wireless/sme.c                           |   12 +-
 net/wireless/wext-core.c                     | 1063 +++++++++++++++
 net/wireless/wext-priv.c                     |  248 ++++
 net/wireless/wext-proc.c                     |  155 +++
 net/wireless/wext-spy.c                      |  231 ++++
 net/wireless/wext.c                          | 1775 --------------------------
 142 files changed, 6953 insertions(+), 5229 deletions(-)
 create mode 100644 drivers/net/wireless/ath/debug.c
 create mode 100644 drivers/net/wireless/ath/debug.h
 create mode 100644 drivers/net/wireless/ath/hw.c
 create mode 100644 drivers/net/wireless/ath/reg.h
 create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.c
 create mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-led.h
 create mode 100644 drivers/net/wireless/iwlwifi/iwl-devtrace.c
 create mode 100644 drivers/net/wireless/iwlwifi/iwl-devtrace.h
 create mode 100644 drivers/net/wireless/libertas/Kconfig
 create mode 100644 drivers/net/wireless/libertas/cfg.c
 create mode 100644 drivers/net/wireless/libertas/cfg.h
 delete mode 100644 drivers/net/wireless/wl12xx/wl1251_netlink.h
 create mode 100644 net/wireless/ethtool.c
 create mode 100644 net/wireless/ethtool.h
 create mode 100644 net/wireless/wext-core.c
 create mode 100644 net/wireless/wext-priv.c
 create mode 100644 net/wireless/wext-proc.c
 create mode 100644 net/wireless/wext-spy.c
 delete mode 100644 net/wireless/wext.c

Omnibus patch is available here:

	http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2009-10-09.patch.bz2

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* [PATCH 17/17] iwlwifi: update channel switch command API
From: Reinette Chatre @ 2009-10-09 20:20 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1255119634-3060-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Channel switch host command has different data structure for
different devices. Adding additional structures to support 5000 and 6000
NICs. unlike 4965, starting with 5000 series, the tx power is managed by
uCode, there is no tx power db information need to be passing from driver to
uCode; but the space needs to be reserved to match uCode expection.

1000 NIC do not support channel switch operation since it is 'bgn'
device, there is no need to have data structure defined for it.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-commands.h |   47 ++++++++++++++++++++++++++-
 1 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 2e8a55e..cc4e912 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -353,6 +353,9 @@ struct iwl3945_power_per_rate {
 #define POWER_TABLE_NUM_HT_OFDM_ENTRIES		32
 #define POWER_TABLE_CCK_ENTRY			32
 
+#define IWL_PWR_NUM_HT_OFDM_ENTRIES		24
+#define IWL_PWR_CCK_ENTRIES			2
+
 /**
  * union iwl4965_tx_power_dual_stream
  *
@@ -803,7 +806,7 @@ struct iwl3945_channel_switch_cmd {
 	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
 } __attribute__ ((packed));
 
-struct iwl_channel_switch_cmd {
+struct iwl4965_channel_switch_cmd {
 	u8 band;
 	u8 expect_beacon;
 	__le16 channel;
@@ -813,6 +816,48 @@ struct iwl_channel_switch_cmd {
 	struct iwl4965_tx_power_db tx_power;
 } __attribute__ ((packed));
 
+/**
+ * struct iwl5000_channel_switch_cmd
+ * @band: 0- 5.2GHz, 1- 2.4GHz
+ * @expect_beacon: 0- resume transmits after channel switch
+ *		   1- wait for beacon to resume transmits
+ * @channel: new channel number
+ * @rxon_flags: Rx on flags
+ * @rxon_filter_flags: filtering parameters
+ * @switch_time: switch time in extended beacon format
+ * @reserved: reserved bytes
+ */
+struct iwl5000_channel_switch_cmd {
+	u8 band;
+	u8 expect_beacon;
+	__le16 channel;
+	__le32 rxon_flags;
+	__le32 rxon_filter_flags;
+	__le32 switch_time;
+	__le32 reserved[2][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES];
+} __attribute__ ((packed));
+
+/**
+ * struct iwl6000_channel_switch_cmd
+ * @band: 0- 5.2GHz, 1- 2.4GHz
+ * @expect_beacon: 0- resume transmits after channel switch
+ *		   1- wait for beacon to resume transmits
+ * @channel: new channel number
+ * @rxon_flags: Rx on flags
+ * @rxon_filter_flags: filtering parameters
+ * @switch_time: switch time in extended beacon format
+ * @reserved: reserved bytes
+ */
+struct iwl6000_channel_switch_cmd {
+	u8 band;
+	u8 expect_beacon;
+	__le16 channel;
+	__le32 rxon_flags;
+	__le32 rxon_filter_flags;
+	__le32 switch_time;
+	__le32 reserved[3][IWL_PWR_NUM_HT_OFDM_ENTRIES + IWL_PWR_CCK_ENTRIES];
+} __attribute__ ((packed));
+
 /*
  * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
  */
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 16/17] iwl3945: rearrange the code.
From: Reinette Chatre @ 2009-10-09 20:20 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Abhijeet Kolekar, Reinette Chatre
In-Reply-To: <1255119634-3060-1-git-send-email-reinette.chatre@intel.com>

From: Abhijeet Kolekar <abhijeet.kolekar@intel.com>

Rearrange the code and groups setting of
retry_limit and data_retry_limits code together.
Make 'data_retry_limit' setting similar to iwlwifi
for better readability.

Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-3945.c |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index eb874e0..8012381 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -794,17 +794,22 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
 	 * in this running context */
 	rate_mask = IWL_RATES_MASK;
 
+
+	/* Set retry limit on DATA packets and Probe Responses*/
+	if (ieee80211_is_probe_resp(fc))
+		data_retry_limit = 3;
+	else
+		data_retry_limit = IWL_DEFAULT_TX_RETRY;
+	tx_cmd->data_retry_limit = data_retry_limit;
+
 	if (tx_id >= IWL_CMD_QUEUE_NUM)
 		rts_retry_limit = 3;
 	else
 		rts_retry_limit = 7;
 
-	if (ieee80211_is_probe_resp(fc)) {
-		data_retry_limit = 3;
-		if (data_retry_limit < rts_retry_limit)
-			rts_retry_limit = data_retry_limit;
-	} else
-		data_retry_limit = IWL_DEFAULT_TX_RETRY;
+	if (data_retry_limit < rts_retry_limit)
+		rts_retry_limit = data_retry_limit;
+	tx_cmd->rts_retry_limit = rts_retry_limit;
 
 	if (ieee80211_is_mgmt(fc)) {
 		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
@@ -822,8 +827,6 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
 		}
 	}
 
-	tx_cmd->rts_retry_limit = rts_retry_limit;
-	tx_cmd->data_retry_limit = data_retry_limit;
 	tx_cmd->rate = rate;
 	tx_cmd->tx_flags = tx_flags;
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 15/17] iwlwifi/iwl3945: remove data_retry_limit
From: Reinette Chatre @ 2009-10-09 20:20 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Abhijeet Kolekar, Reinette Chatre
In-Reply-To: <1255119634-3060-1-git-send-email-reinette.chatre@intel.com>

From: Abhijeet Kolekar <abhijeet.kolekar@intel.com>

Remove the ununsed variable data_retry_limit
from priv.

Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-3945.c     |    3 ---
 drivers/net/wireless/iwlwifi/iwl-core.c     |    1 -
 drivers/net/wireless/iwlwifi/iwl-dev.h      |    1 -
 drivers/net/wireless/iwlwifi/iwl-tx.c       |    4 +---
 drivers/net/wireless/iwlwifi/iwl3945-base.c |    1 -
 5 files changed, 1 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index a6944bc..eb874e0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -806,9 +806,6 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
 	} else
 		data_retry_limit = IWL_DEFAULT_TX_RETRY;
 
-	if (priv->data_retry_limit != -1)
-		data_retry_limit = priv->data_retry_limit;
-
 	if (ieee80211_is_mgmt(fc)) {
 		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
 		case cpu_to_le16(IEEE80211_STYPE_AUTH):
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1e0021f..2ae168a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1524,7 +1524,6 @@ int iwl_init_drv(struct iwl_priv *priv)
 	/* Clear the driver's (not device's) station table */
 	iwl_clear_stations_table(priv);
 
-	priv->data_retry_limit = -1;
 	priv->ieee_channels = NULL;
 	priv->ieee_rates = NULL;
 	priv->band = IEEE80211_BAND_2GHZ;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 8d087f0..451aa65 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1092,7 +1092,6 @@ struct iwl_priv {
 	u8 last_phy_res[100];
 
 	/* Rate scaling data */
-	s8 data_retry_limit;
 	u8 retry_rate;
 
 	wait_queue_head_t wait_command_queue;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 625da63..d0bd7cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -591,9 +591,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
 	u8 rate_plcp;
 
 	/* Set retry limit on DATA packets and Probe Responses*/
-	if (priv->data_retry_limit != -1)
-		data_retry_limit = priv->data_retry_limit;
-	else if (ieee80211_is_probe_resp(fc))
+	if (ieee80211_is_probe_resp(fc))
 		data_retry_limit = 3;
 	else
 		data_retry_limit = IWL_DEFAULT_TX_RETRY;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 03612b3..515f29b 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3797,7 +3797,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
 	/* Clear the driver's (not device's) station table */
 	iwl_clear_stations_table(priv);
 
-	priv->data_retry_limit = -1;
 	priv->ieee_channels = NULL;
 	priv->ieee_rates = NULL;
 	priv->band = IEEE80211_BAND_2GHZ;
-- 
1.5.6.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox