Date: Thu, 28 Sep 2006 13:41:39 -0400 From: "John W. Linville" <linville@redhat.com> Subject: [rhel5 patch] ipw2200: update to version 1.2.0 from ipw2200.sf.net Here is a patch to update the ipw2200 driver to Intel's version 1.2.0 from ipw2200.sf.net. I removed the multiple kernel version compatibility stuff, but otherwise it is the same as from their website. No, I'm not super happy about this. But, using a "blessed" driver from Intel is the only way for a vendor to qualify to use the Centrino brand with hardware that might come preloaded with RHEL5. Besides, there must be some good stuff in there... :-) BZ184862 Tested by both Intel and me, with affirmative results. drivers/net/wireless/README.ipw2200 | 451 +++++++++++++++++++++++++++++++++ drivers/net/wireless/ipw2200.c | 485 +++++++++++++++++++----------------- drivers/net/wireless/ipw2200.h | 64 ++-- 3 files changed, 751 insertions(+), 249 deletions(-) --- linux-2.6.18.noarch/drivers/net/wireless/README.ipw2200.orig 2006-09-26 14:20:47.000000000 -0400 +++ linux-2.6.18.noarch/drivers/net/wireless/README.ipw2200 2006-09-26 14:21:06.000000000 -0400 @@ -0,0 +1,463 @@ + +Intel(R) PRO/Wireless 2915ABG Network Connection driver for Linux +in support of: + +Intel(R) PRO/Wireless 2200BG Network Connection +Intel(R) PRO/Wireless 2915ABG Network Connection + +Note: The Intel(R) PRO/Wireless 2915ABG driver for Linux and Intel(R) +PRO/Wireless 2200BG driver for Linux is a unified driver that works on +both hardware adapters listed above. In this document the Intel(R) +PRO/Wireless 2915ABG driver for Linux will be used to refer to the +unified driver. + +Copyright (C) 2004-2006, Intel Corporation + +INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. +EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH +PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER, AND INTEL DISCLAIMS +ANY EXPRESS OR IMPLIED WARRANTY RELATING TO SALE AND/OR USE OF INTEL +PRODUCTS, INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A +PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, +COPYRIGHT, OR OTHER INTELLECTUAL PROPERTY RIGHT. +This document is subject to change without notice. +* Other names and brands may be claimed as the property of others. + + +README.ipw2200 + +Version: 1.2.0 +Date : September 12, 2006 + + +Index +----------------------------------------------- +0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER +1. Introduction +1.1. Overview of features +1.2. Module parameters +1.3. Wireless Extension Private Methods +1.4. Sysfs Helper Files +2. Ad-Hoc Networking +3. Interacting with Wireless Tools +3.1. iwconfig mode +4. About the Version Numbers +5. Firmware installation +6. Support +7. License + + +0. IMPORTANT INFORMATION BEFORE USING THIS DRIVER +----------------------------------------------- + +Important Notice FOR ALL USERS OR DISTRIBUTORS!!!! + +Intel wireless LAN adapters are engineered, manufactured, tested, and +quality checked to ensure that they meet all necessary local and +governmental regulatory agency requirements for the regions that they +are designated and/or marked to ship into. Since wireless LANs are +generally unlicensed devices that share spectrum with radars, +satellites, and other licensed and unlicensed devices, it is sometimes +necessary to dynamically detect, avoid, and limit usage to avoid +interference with these devices. In many instances Intel is required to +provide test data to prove regional and local compliance to regional and +governmental regulations before certification or approval to use the +product is granted. Intel's wireless LAN's EEPROM, firmware, and +software driver are designed to carefully control parameters that affect +radio operation and to ensure electromagnetic compliance (EMC). These +parameters include, without limitation, RF power, spectrum usage, +channel scanning, and human exposure. + +For these reasons Intel cannot permit any manipulation by third parties +of the software provided in binary format with the wireless WLAN +adapters (e.g., the EEPROM and firmware). Furthermore, if you use any +patches, utilities, or code with the Intel wireless LAN adapters that +have been manipulated by an unauthorized party (i.e., patches, +utilities, or code (including open source code modifications) which have +not been validated by Intel), (i) you will be solely responsible for +ensuring the regulatory compliance of the products, (ii) Intel will bear +no liability, under any theory of liability for any issues associated +with the modified products, including without limitation, claims under +the warranty and/or issues arising from regulatory non-compliance, and +(iii) Intel will not provide or be required to assist in providing +support to any third parties for such modified products. + +Note: Many regulatory agencies consider Wireless LAN adapters to be +modules, and accordingly, condition system-level regulatory approval +upon receipt and review of test data documenting that the antennas and +system configuration do not cause the EMC and radio operation to be +non-compliant. + +The drivers available for download from SourceForge are provided as a +part of a development project. Conformance to local regulatory +requirements is the responsibility of the individual developer. As +such, if you are interested in deploying or shipping a driver as part of +solution intended to be used for purposes other than development, please +obtain a tested driver from Intel Customer Support at: + +http://support.intel.com/support/notebook/sb/CS-006408.htm + + +1. Introduction +----------------------------------------------- +The following sections attempt to provide a brief introduction to use +the Intel(R) PRO/Wireless 2915ABG Driver for Linux. + +This document is not meant to be a comprehensive manual on +understanding or using wireless technologies, but should be sufficient +to get you moving without wires on Linux. + +For information on building and installing the Intel PRO/Wireless +2915ABG Network Connection driver, see the INSTALL file. + + +1.1. Overview of Features +----------------------------------------------- +The current release (1.2.0) supports the following features: + ++ BSS mode (Infrastructure, Managed) ++ IBSS mode (Ad-Hoc) ++ WEP (OPEN and SHARED KEY mode) ++ 802.1x EAP via wpa_supplicant and xsupplicant ++ Wireless Extension support ++ Full B and G rate support (2200 and 2915) ++ Full A rate support (2915 only) ++ Transmit power control ++ S state support (ACPI suspend/resume) + +The following features are currently enabled, but not officially +supported: + ++ WPA ++ long/short preamble support ++ Monitor mode (aka RFMon) + +The distinction between officially supported and enabled is a reflection +of the amount of validation and interoperability testing that has been +performed on a given feature. + + + +1.2. Command Line Parameters +----------------------------------------------- + +Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless +2915ABG Driver for Linux allows configuration options to be provided +as module parameters. The most common way to specify a module parameter +is command line. + +The general form is: + +% modprobe ipw2200 [parameter]=[value] + +Where the supported parameter are: + + associate + Setting to 0 to disable the auto scan-and-associate functionality of the + driver. If disabled, the driver will not attempt to scan + for and associate to a network until it has been configured with + one or more properties to the target network, such as configuring + the network SSID. Default is 1 (auto-associate) + + Example: % modprobe ipw2200 associate=0 + + auto_create + Setting to 0 to disable the auto creation of an Ad-Hoc network + matching the channel and network name parameters provided. + Default is 1. + + channel + channel number for association. The general method for setting + the channel is to use the standard wireless tools + (i.e. `iwconfig eth1 channel 10`), but it is useful sometimes + to set this while debugging. Channel 0 means 'ANY' + + debug + If using a debug build, this is used to control the amount of debug + info to be logged. See the 'dvals' and 'load' script for more info on + how to use this (the dvals and load scripts are provided as part + of the Intel PRO/Wireless 2915ABG Network Connection driver + development snapshot releases available from the SourceForge project + at http://ipw2200.sf.net) + + led + Can be used to turn on experimental LED code. + 0 = Off, 1 = On. Default is 0. + + mode + Can be used to set the default mode of the adapter. + 0 = Managed, 1 = Ad-Hoc, 2 = Monitor + + ifname + Rename the wireless network interface. It is not supported now. + This parameter was a hack pre-dating the ifrename utility and + has now been superseded by it. The ifrename utility can be found + in the wireless-tool package. Following is an example to change + the default name of wireless interface eth%d to wlan%d. + + create (or edit) file /etc/iftab and append a line to it, such as: + wlan* driver ipw2200 + + then modified /etc/modprobe.conf and added this line: + install ipw2200 /sbin/modprobe --ignore-install ipw2200; /usr/sbin/ifrename + + Please refer to the manpage of ifrename for details. + + +1.3. Wireless Extension Private Methods +----------------------------------------------- + +Since an interface is designed to handle generic hardware, there are certain +capabilities not exposed through the normal Wireless Tool interface. As +such, a provision is provided for a driver to declare custom, or +private, methods. The Intel(R) PRO/Wireless 2915ABG Driver for Linux +defines several of these to configure various settings. + +The general form of using the private wireless methods is: + + % iwpriv $IFNAME method parameters + +Where $IFNAME is the interface name the device is registered with +(typically eth1, customized via one of the various network interface +name managers, such as ifrename) + +The supported private methods are: + + get_mode + Can be used to report out which IEEE mode the driver is + configured to support. Example: + + % iwpriv eth1 get_mode + eth1 get_mode:802.11bg (6) + + set_mode + Can be used to configure which IEEE mode the driver will + support. + + Usage: + % iwpriv eth1 set_mode {mode} + Where {mode} is a number in the range 1-7: + 1 802.11a (2915 only) + 2 802.11b + 3 802.11ab (2915 only) + 4 802.11g + 5 802.11ag (2915 only) + 6 802.11bg + 7 802.11abg (2915 only) + + get_preamble + Can be used to report configuration of preamble length. + + set_preamble + Can be used to set the configuration of preamble length: + + Usage: + % iwpriv eth1 set_preamble {mode} + Where {mode} is one of: + 1 Long preamble only + 0 Auto (long or short based on connection) + + +1.4. Sysfs Helper Files: +----------------------------------------------- + +The Linux kernel provides a pseudo file system that can be used to +access various components of the operating system. The Intel(R) +PRO/Wireless 2915ABG Driver for Linux exposes several configuration +parameters through this mechanism. + +An entry in the sysfs can support reading and/or writing. You can +typically query the contents of a sysfs entry through the use of cat, +and can set the contents via echo. For example: + +% cat /sys/bus/pci/drivers/ipw2200/debug_level + +Will report the current debug level of the driver's logging subsystem +(only available if CONFIG_IPW2200_DEBUG was configured when the driver +was built). + +You can set the debug level via: + +% echo $VALUE > /sys/bus/pci/drivers/ipw2200/debug_level + +Where $VALUE would be a number in the case of this sysfs entry. The +input to sysfs files does not have to be a number. For example, the +firmware loader used by hotplug utilizes sysfs entries for transfering +the firmware image from user space into the driver. + +The Intel(R) PRO/Wireless 2915ABG Driver for Linux exposes sysfs entries +at two levels -- driver level, which apply to all instances of the driver +(in the event that there is more than one device installed) and device +level, which applies only to the single specific instance. + + +1.4.1 Driver Level Sysfs Helper Files +----------------------------------------------- + +For the Intel PRO/Wireless 2915ABG Network Connection driver +level files, look in /sys/bus/pci/drivers/ipw2200/ + + debug_level + + This controls the same global as the 'debug' module parameter + + + +1.4.2 Device Level Sysfs Helper Files +----------------------------------------------- + +For the device level files, look in + + /sys/bus/pci/drivers/ipw2200/{PCI-ID}/ + +For example: + /sys/bus/pci/drivers/ipw2200/0000:02:01.0 + +For the device level files, see /sys/bus/pci/drivers/ipw2200: + + rf_kill + read - + 0 = RF kill not enabled (radio on) + 1 = SW based RF kill active (radio off) + 2 = HW based RF kill active (radio off) + 3 = Both HW and SW RF kill active (radio off) + write - + 0 = If SW based RF kill active, turn the radio back on + 1 = If radio is on, activate SW based RF kill + + NOTE: If you enable the SW based RF kill and then toggle the HW + based RF kill from ON -> OFF -> ON, the radio will NOT come back on + + ucode + read-only access to the ucode version number + + led + read - + 0 = LED code disabled + 1 = LED code enabled + write - + 0 = Disable LED code + 1 = Enable LED code + + NOTE: The LED code has been reported to hang some systems when + running ifconfig and is therefore disabled by default. + + +2. Ad-Hoc Networking +----------------------------------------------- + +When using a device in an Ad-Hoc network, it is useful to understand the +sequence and requirements for the Intel PRO/Wireless 2915ABG +Network Connection driver to be able to create, join, or merge networks. + +The following attempts to provide enough information so that you can +have a consistent experience while using the Intel PRO/Wireless 2915ABG +Network Connection driver as a member of an ad-hoc network. + +2.1. Joining an Ad-Hoc Network +----------------------------------------------- + +The easiest way to get onto an Ad-Hoc network is to join one that +already exists. + +2.2. Creating an Ad-Hoc Network +----------------------------------------------- + +An Ad-Hoc networks is created using the syntax of the Wireless tool. + +For Example: +iwconfig eth1 mode ad-hoc essid testing channel 2 + +2.3. Merging Ad-Hoc Networks +----------------------------------------------- + + +3. Interaction with Wireless Tools +----------------------------------------------- + +3.1 iwconfig mode +----------------------------------------------- + +When configuring the mode of the adapter, all run-time configured parameters +are reset to the value used when the module was loaded. This includes +channels, rates, ESSID, etc. + + +4. About the Version Numbers +----------------------------------------------- + +Due to the nature of open source development projects, there are +frequently changes being incorporated that have not gone through +a complete validation process. These changes are incorporated into +development snapshot releases. + +Releases are numbered with a three level scheme: + + major.minor.development + +Any version where the 'development' portion is 0 (for example +1.0.0, 1.2.0, etc.) indicates a stable version that will be made +available for kernel inclusion. + +Any version where the 'development' portion is not a 0 (for +example 1.0.1, 1.1.5, etc.) indicates a development version that is +being made available for testing and cutting edge users. The stability +and functionality of the development releases are not know. We make +efforts to try and keep all snapshots reasonably stable, but due to the +frequency of their release, and the desire to get those releases +available as quickly as possible, unknown anomalies should be expected. + +The major version number will be incremented when significant changes +are made to the Intel PRO/Wireless 2915ABG Network Connection +driver. Currently, there are no major changes planned. + +5. Firmware installation +---------------------------------------------- + +The Intel PRO/Wireless 2915ABG Network Connection driver +requires a firmware image, download it and extract the files under +/lib/firmware (or wherever your hotplug's firmware.agent will look +for firmware files) + +The firmware can be downloaded from the following URL: + + http://ipw2200.sf.net/ + + +6. Support +----------------------------------------------- + +For direct support of the 1.0.0 version, you can contact +http://supportmail.intel.com, or you can use the open source project +support. + +For general information and support, go to: + + http://ipw2200.sf.net/ + + +7. License +----------------------------------------------- + + Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License 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., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos <ipw2100-admin@linux.intel.com> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + --- linux-2.6.18.noarch/drivers/net/wireless/ipw2200.h.orig 2006-09-26 14:20:41.000000000 -0400 +++ linux-2.6.18.noarch/drivers/net/wireless/ipw2200.h 2006-09-26 14:22:05.000000000 -0400 @@ -713,7 +716,6 @@ struct ipw_rx_mem_buffer { dma_addr_t dma_addr; - struct ipw_rx_buffer *rxb; struct sk_buff *skb; struct list_head list; }; /* Not transferred over network, so not __attribute__ ((packed)) */ @@ -1127,7 +1129,7 @@ IPW_PROM_CTL_HEADER_ONLY = (1 << 0), IPW_PROM_MGMT_HEADER_ONLY = (1 << 1), IPW_PROM_DATA_HEADER_ONLY = (1 << 2), - IPW_PROM_ALL_HEADER_ONLY = 0xf, /* bits 0..3 */ + IPW_PROM_ALL_HEADER_ONLY = 0xf, /* bits 0..3 */ IPW_PROM_NO_TX = (1 << 4), IPW_PROM_NO_RX = (1 << 5), IPW_PROM_NO_CTL = (1 << 6), @@ -1155,15 +1157,15 @@ */ struct ipw_rt_hdr { struct ieee80211_radiotap_header rt_hdr; - u64 rt_tsf; /* TSF */ - u8 rt_flags; /* radiotap packet flags */ - u8 rt_rate; /* rate in 500kb/s */ - u16 rt_channel; /* channel in mhz */ + u64 rt_tsf; /* TSF */ + u8 rt_flags; /* radiotap packet flags */ + u8 rt_rate; /* rate in 500kb/s */ + u16 rt_channel; /* channel in mhz */ u16 rt_chbitmask; /* channel bitfield */ s8 rt_dbmsignal; /* signal in dbM, kluged to signed */ s8 rt_dbmnoise; - u8 rt_antenna; /* antenna number */ - u8 payload[0]; /* payload... */ + u8 rt_antenna; /* antenna number */ + u8 payload[0]; /* payload... */ } __attribute__ ((packed)); #endif @@ -1297,6 +1301,7 @@ struct work_struct system_config; struct work_struct rx_replenish; struct work_struct request_scan; + struct work_struct request_passive_scan; struct work_struct adapter_restart; struct work_struct rf_kill; struct work_struct up; @@ -1380,14 +1385,18 @@ BITC(x,19),BITC(x,18),BITC(x,17),BITC(x,16),\ BIT_ARG16(x) +#define IPW_DEBUG(level, fmt, args...) \ +do { if (ipw_debug_level & (level)) \ + printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \ + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) #ifdef CONFIG_IPW2200_DEBUG -#define IPW_DEBUG(level, fmt, args...) \ +#define IPW_LL_DEBUG(level, fmt, args...) \ do { if (ipw_debug_level & (level)) \ printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \ in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) #else -#define IPW_DEBUG(level, fmt, args...) do {} while (0) +#define IPW_LL_DEBUG(level, fmt, args...) do {} while (0) #endif /* CONFIG_IPW2200_DEBUG */ /* @@ -1457,28 +1466,27 @@ #define IPW_DEBUG_WX(f, a...) IPW_DEBUG(IPW_DL_WX, f, ## a) #define IPW_DEBUG_SCAN(f, a...) IPW_DEBUG(IPW_DL_SCAN, f, ## a) -#define IPW_DEBUG_STATUS(f, a...) IPW_DEBUG(IPW_DL_STATUS, f, ## a) -#define IPW_DEBUG_TRACE(f, a...) IPW_DEBUG(IPW_DL_TRACE, f, ## a) -#define IPW_DEBUG_RX(f, a...) IPW_DEBUG(IPW_DL_RX, f, ## a) -#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a) -#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a) +#define IPW_DEBUG_TRACE(f, a...) IPW_LL_DEBUG(IPW_DL_TRACE, f, ## a) +#define IPW_DEBUG_RX(f, a...) IPW_LL_DEBUG(IPW_DL_RX, f, ## a) +#define IPW_DEBUG_TX(f, a...) IPW_LL_DEBUG(IPW_DL_TX, f, ## a) +#define IPW_DEBUG_ISR(f, a...) IPW_LL_DEBUG(IPW_DL_ISR, f, ## a) #define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a) -#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a) -#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a) -#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) -#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a) -#define IPW_DEBUG_FW(f, a...) IPW_DEBUG(IPW_DL_FW, f, ## a) +#define IPW_DEBUG_LED(f, a...) IPW_LL_DEBUG(IPW_DL_LED, f, ## a) +#define IPW_DEBUG_WEP(f, a...) IPW_LL_DEBUG(IPW_DL_WEP, f, ## a) +#define IPW_DEBUG_HC(f, a...) IPW_LL_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) +#define IPW_DEBUG_FRAG(f, a...) IPW_LL_DEBUG(IPW_DL_FRAG, f, ## a) +#define IPW_DEBUG_FW(f, a...) IPW_LL_DEBUG(IPW_DL_FW, f, ## a) #define IPW_DEBUG_RF_KILL(f, a...) IPW_DEBUG(IPW_DL_RF_KILL, f, ## a) #define IPW_DEBUG_DROP(f, a...) IPW_DEBUG(IPW_DL_DROP, f, ## a) -#define IPW_DEBUG_IO(f, a...) IPW_DEBUG(IPW_DL_IO, f, ## a) -#define IPW_DEBUG_ORD(f, a...) IPW_DEBUG(IPW_DL_ORD, f, ## a) -#define IPW_DEBUG_FW_INFO(f, a...) IPW_DEBUG(IPW_DL_FW_INFO, f, ## a) +#define IPW_DEBUG_IO(f, a...) IPW_LL_DEBUG(IPW_DL_IO, f, ## a) +#define IPW_DEBUG_ORD(f, a...) IPW_LL_DEBUG(IPW_DL_ORD, f, ## a) +#define IPW_DEBUG_FW_INFO(f, a...) IPW_LL_DEBUG(IPW_DL_FW_INFO, f, ## a) #define IPW_DEBUG_NOTIF(f, a...) IPW_DEBUG(IPW_DL_NOTIF, f, ## a) #define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) #define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) -#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a) -#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a) -#define IPW_DEBUG_QOS(f, a...) IPW_DEBUG(IPW_DL_QOS, f, ## a) +#define IPW_DEBUG_STATS(f, a...) IPW_LL_DEBUG(IPW_DL_STATS, f, ## a) +#define IPW_DEBUG_MERGE(f, a...) IPW_LL_DEBUG(IPW_DL_MERGE, f, ## a) +#define IPW_DEBUG_QOS(f, a...) IPW_LL_DEBUG(IPW_DL_QOS, f, ## a) #include <linux/ctype.h> @@ -1947,10 +1955,17 @@ u32 *param; } __attribute__ ((packed)); +struct cmdlog_host_cmd { + u8 cmd; + u8 len; + u16 reserved; + char param[124]; +} __attribute__ ((packed)); + struct ipw_cmd_log { unsigned long jiffies; int retcode; - struct host_cmd cmd; + struct cmdlog_host_cmd cmd; }; /* SysConfig command parameters ... */ --- linux-2.6.18.noarch/drivers/net/wireless/ipw2200.c.orig 2006-09-26 14:20:37.000000000 -0400 +++ linux-2.6.18.noarch/drivers/net/wireless/ipw2200.c 2006-09-26 14:25:00.000000000 -0400 @@ -33,7 +33,6 @@ #include "ipw2200.h" #include <linux/version.h> - #ifndef KBUILD_EXTMOD #define VK "k" #else @@ -70,7 +69,7 @@ #define VQ #endif -#define IPW2200_VERSION "1.1.2" VK VD VM VP VR VQ +#define IPW2200_VERSION "1.2.0" VK VD VM VP VR VQ #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" #define DRV_VERSION IPW2200_VERSION @@ -83,9 +82,7 @@ MODULE_LICENSE("GPL"); static int cmdlog = 0; -#ifdef CONFIG_IPW2200_DEBUG static int debug = 0; -#endif static int channel = 0; static int mode = 0; @@ -103,10 +100,9 @@ static int antenna = CFG_SYS_ANTENNA_BOTH; #ifdef CONFIG_IPW2200_PROMISCUOUS -static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ +static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ #endif - #ifdef CONFIG_IPW2200_QOS static int qos_enable = 0; static int qos_burst_enable = 0; @@ -567,7 +568,6 @@ spin_unlock_irqrestore(&priv->irq_lock, flags); } -#ifdef CONFIG_IPW2200_DEBUG static char *ipw_error_desc(u32 val) { switch (val) { @@ -634,7 +634,6 @@ error->log[i].time, error->log[i].data, error->log[i].event); } -#endif static inline int ipw_is_init(struct ipw_priv *priv) { @@ -960,7 +959,7 @@ __ipw_led_activity_on(priv); spin_unlock_irqrestore(&priv->lock, flags); } -#endif /* 0 */ +#endif /* 0 */ static void ipw_led_activity_off(struct ipw_priv *priv) { @@ -1230,7 +1229,8 @@ } static ssize_t show_event_log(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); u32 log_len = ipw_get_event_log_len(priv); @@ -1251,7 +1253,8 @@ static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL); static ssize_t show_error(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); u32 len = 0, i; @@ -1299,7 +1306,8 @@ static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error); static ssize_t show_cmd_log(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); u32 len = 0, i; @@ -1329,8 +1339,8 @@ static void ipw_prom_free(struct ipw_priv *priv); static int ipw_prom_alloc(struct ipw_priv *priv); static ssize_t store_rtap_iface(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); int rc = 0; @@ -1374,8 +1386,8 @@ } static ssize_t show_rtap_iface(struct device *d, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); if (rtap_iface) @@ -1392,8 +1406,8 @@ store_rtap_iface); static ssize_t store_rtap_filter(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1412,8 +1428,8 @@ } static ssize_t show_rtap_filter(struct device *d, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "0x%04X", @@ -1424,20 +1442,20 @@ store_rtap_filter); #endif -static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, +static ssize_t show_scan_age(struct device *d, + struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", priv->ieee->scan_age); } -static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, +static ssize_t store_scan_age(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); -#ifdef CONFIG_IPW2200_DEBUG struct net_device *dev = priv->net_dev; -#endif char buffer[] = "00000000"; unsigned long len = (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1; @@ -1469,14 +1491,16 @@ static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age); -static ssize_t show_led(struct device *d, struct device_attribute *attr, +static ssize_t show_led(struct device *d, + struct device_attribute *attr, char *buf) { struct ipw_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1); } -static ssize_t store_led(struct device *d, struct device_attribute *attr, +static ssize_t store_led(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); @@ -1503,7 +1531,8 @@ static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led); static ssize_t show_status(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct ipw_priv *p = d->driver_data; return sprintf(buf, "0x%08x\n", (int)p->status); @@ -1511,7 +1542,8 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); -static ssize_t show_cfg(struct device *d, struct device_attribute *attr, +static ssize_t show_cfg(struct device *d, + struct device_attribute *attr, char *buf) { struct ipw_priv *p = d->driver_data; @@ -1521,7 +1555,8 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); static ssize_t show_nic_type(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct ipw_priv *priv = d->driver_data; return sprintf(buf, "TYPE: %d\n", priv->nic_type); @@ -1530,7 +1567,8 @@ static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); static ssize_t show_ucode_version(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { u32 len = sizeof(u32), tmp = 0; struct ipw_priv *p = d->driver_data; @@ -1543,7 +1583,8 @@ static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL); -static ssize_t show_rtc(struct device *d, struct device_attribute *attr, +static ssize_t show_rtc(struct device *d, + struct device_attribute *attr, char *buf) { u32 len = sizeof(u32), tmp = 0; @@ -1562,7 +1605,8 @@ * operations. */ static ssize_t show_eeprom_delay(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay; return sprintf(buf, "%i\n", n); @@ -1580,7 +1628,8 @@ show_eeprom_delay, store_eeprom_delay); static ssize_t show_command_event_reg(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { u32 reg = 0; struct ipw_priv *p = d->driver_data; @@ -1604,7 +1657,8 @@ show_command_event_reg, store_command_event_reg); static ssize_t show_mem_gpio_reg(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { u32 reg = 0; struct ipw_priv *p = d->driver_data; @@ -1628,7 +1686,8 @@ show_mem_gpio_reg, store_mem_gpio_reg); static ssize_t show_indirect_dword(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { u32 reg = 0; struct ipw_priv *priv = d->driver_data; @@ -1655,7 +1718,8 @@ show_indirect_dword, store_indirect_dword); static ssize_t show_indirect_byte(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { u8 reg = 0; struct ipw_priv *priv = d->driver_data; @@ -1682,7 +1750,8 @@ show_indirect_byte, store_indirect_byte); static ssize_t show_direct_dword(struct device *d, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { u32 reg = 0; struct ipw_priv *priv = d->driver_data; @@ -1718,7 +1791,8 @@ return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0; } -static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, +static ssize_t show_rf_kill(struct device *d, + struct device_attribute *attr, char *buf) { /* 0 - RF kill not enabled @@ -1762,7 +1838,8 @@ return 1; } -static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, +static ssize_t store_rf_kill(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = d->driver_data; @@ -1774,7 +1853,8 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); -static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr, +static ssize_t show_speed_scan(struct device *d, + struct device_attribute *attr, char *buf) { struct ipw_priv *priv = (struct ipw_priv *)d->driver_data; @@ -1789,7 +1871,8 @@ return sprintf(buf, "0\n"); } -static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr, +static ssize_t store_speed_scan(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = (struct ipw_priv *)d->driver_data; @@ -1828,14 +1913,16 @@ static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan, store_speed_scan); -static ssize_t show_net_stats(struct device *d, struct device_attribute *attr, +static ssize_t show_net_stats(struct device *d, + struct device_attribute *attr, char *buf) { struct ipw_priv *priv = (struct ipw_priv *)d->driver_data; return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0'); } -static ssize_t store_net_stats(struct device *d, struct device_attribute *attr, +static ssize_t store_net_stats(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) { struct ipw_priv *priv = (struct ipw_priv *)d->driver_data; @@ -1958,14 +2049,12 @@ IPW_WARNING("Firmware error detected. Restarting.\n"); if (priv->error) { IPW_DEBUG_FW("Sysfs 'error' log already exists.\n"); -#ifdef CONFIG_IPW2200_DEBUG if (ipw_debug_level & IPW_DL_FW_ERRORS) { struct ipw_fw_error *error = ipw_alloc_error_log(priv); ipw_dump_error_log(priv, error); kfree(error); } -#endif } else { priv->error = ipw_alloc_error_log(priv); if (priv->error) @@ -1973,10 +2062,8 @@ else IPW_DEBUG_FW("Error allocating sysfs 'error' " "log.\n"); -#ifdef CONFIG_IPW2200_DEBUG if (ipw_debug_level & IPW_DL_FW_ERRORS) ipw_dump_error_log(priv, priv->error); -#endif } /* XXX: If hardware encryption is for WPA/WPA2, @@ -2186,8 +2273,7 @@ static int ipw_send_system_config(struct ipw_priv *priv) { return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, - sizeof(priv->sys_config), - &priv->sys_config); + sizeof(priv->sys_config), &priv->sys_config); } static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) @@ -2287,7 +2373,7 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) { struct ipw_sensitivity_calib calib = { - .beacon_rssi_raw = sens, + .beacon_rssi_raw = cpu_to_le16(sens), }; return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib), @@ -2353,6 +2439,7 @@ return -1; } + phy_off = cpu_to_le32(phy_off); return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off), &phy_off); } @@ -2414,7 +2501,7 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) { struct ipw_rts_threshold rts_threshold = { - .rts_threshold = rts, + .rts_threshold = cpu_to_le16(rts), }; if (!priv) { @@ -2429,7 +2516,7 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) { struct ipw_frag_threshold frag_threshold = { - .frag_threshold = frag, + .frag_threshold = cpu_to_le16(frag), }; if (!priv) { @@ -2464,6 +2551,7 @@ break; } + param = cpu_to_le32(mode); return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), ¶m); } @@ -2667,7 +2755,7 @@ IPW_DEBUG_FW(">> :\n"); - //set the Stop and Abort bit + /* set the Stop and Abort bit */ control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control); priv->sram_desc.last_cb_index = 0; @@ -2930,8 +3018,7 @@ } /* timeout in msec, attempted in 10-msec quanta */ -static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, - int timeout) +static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask, int timeout) { int i = 0; @@ -3002,8 +3089,6 @@ if (rc < 0) return rc; -// spin_lock_irqsave(&priv->lock, flags); - for (addr = IPW_SHARED_LOWER_BOUND; addr < IPW_REGISTER_DOMAIN1_END; addr += 4) { ipw_write32(priv, addr, 0); @@ -3097,8 +3182,6 @@ firmware have problem getting alive resp. */ ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0); -// spin_unlock_irqrestore(&priv->lock, flags); - return rc; } @@ -3255,7 +3338,6 @@ return rc; } - struct ipw_fw { __le32 ver; __le32 boot_size; @@ -3294,15 +3376,13 @@ IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n", name, le32_to_cpu(fw->ver) >> 16, - le32_to_cpu(fw->ver) & 0xff, - (*raw)->size - sizeof(*fw)); + le32_to_cpu(fw->ver) & 0xff, (*raw)->size - sizeof(*fw)); return 0; } #define IPW_RX_BUF_SIZE (3000) -static void ipw_rx_queue_reset(struct ipw_priv *priv, - struct ipw_rx_queue *rxq) +static void ipw_rx_queue_reset(struct ipw_priv *priv, struct ipw_rx_queue *rxq) { unsigned long flags; int i; @@ -3377,7 +3457,6 @@ rc = -EINVAL; goto error; } - #ifdef CONFIG_PM if (!fw_loaded) { #endif @@ -3919,7 +3998,6 @@ {0x2E, "Cipher suite is rejected per security policy"}, }; -#ifdef CONFIG_IPW2200_DEBUG static const char *ipw_get_status_code(u16 status) { int i; @@ -3928,7 +4006,6 @@ return ipw_status_codes[i].reason; return "Unknown status value."; } -#endif static void inline average_init(struct average *avg) { @@ -3939,7 +4016,7 @@ #define DEPTH_NOISE 16 static s16 exponential_average(s16 prev_avg, s16 val, u8 depth) { - return ((depth-1)*prev_avg + val)/depth; + return ((depth - 1) * prev_avg + val) / depth; } static void average_add(struct average *avg, s16 val) @@ -4235,8 +4312,7 @@ * roaming_threshold -> disassociate_threshold, scan and roam for better signal. * Above disassociate threshold, give up and stop scanning. * Roaming is disabled if disassociate_threshold <= roaming_threshold */ -static void ipw_handle_missed_beacon(struct ipw_priv *priv, - int missed_count) +static void ipw_handle_missed_beacon(struct ipw_priv *priv, int missed_count) { priv->notif_missed_beacons = missed_count; @@ -4306,7 +4382,7 @@ * Called from interrupt routine */ static void ipw_rx_notification(struct ipw_priv *priv, - struct ipw_rx_notification *notif) + struct ipw_rx_notification *notif) { notif->size = le16_to_cpu(notif->size); @@ -4398,7 +4474,6 @@ if (priv-> status & (STATUS_ASSOCIATED | STATUS_AUTH)) { -#ifdef CONFIG_IPW2200_DEBUG struct notif_authenticate *auth = ¬if->u.auth; IPW_DEBUG(IPW_DL_NOTIF | @@ -4416,7 +4491,6 @@ ipw_get_status_code (ntohs (auth->status))); -#endif priv->status &= ~(STATUS_ASSOCIATING | @@ -4693,9 +4767,9 @@ if (notif->size == sizeof(*x)) { IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, - "link deterioration: type %d, cnt %d\n", - x->silence_notification_type, - x->silence_count); + "link deterioration: type %d, cnt %d\n", + x->silence_notification_type, + x->silence_count); memcpy(&priv->last_link_deterioration, x, sizeof(*x)); } else { @@ -4768,8 +4842,10 @@ if (notif->size == sizeof(u32)) { priv->exp_avg_noise = exponential_average(priv->exp_avg_noise, - (u8) (le32_to_cpu(notif->u.noise.value) & 0xff), - DEPTH_NOISE); + (u8) (le32_to_cpu + (notif->u.noise. + value) & 0xff), + DEPTH_NOISE); break; } @@ -5059,7 +5135,6 @@ } list_del(element); - rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; rxb->dma_addr = pci_map_single(priv->pci_dev, rxb->skb->data, IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); @@ -5260,7 +5335,7 @@ } static void ipw_copy_rates(struct ipw_supported_rates *dest, - const struct ipw_supported_rates *src) + const struct ipw_supported_rates *src) { u8 i; for (i = 0; i < src->num_rates; i++) @@ -5838,8 +5913,8 @@ key.station_index = 0; /* always 0 for BSS */ key.flags = 0; /* 0 for new key; previous value of counter (after fatal error) */ - key.tx_counter[0] = 0; - key.tx_counter[1] = 0; + key.tx_counter[0] = cpu_to_le32(0); + key.tx_counter[1] = cpu_to_le32(0); ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key); } @@ -5973,7 +6048,6 @@ mutex_unlock(&priv->mutex); } -#ifdef CONFIG_IPW2200_DEBUG static void ipw_debug_config(struct ipw_priv *priv) { IPW_DEBUG_INFO("Scan completed, no valid APs matched " @@ -5998,9 +6072,6 @@ IPW_DEBUG_INFO("PRIVACY off\n"); IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask); } -#else -#define ipw_debug_config(x) do {} while (0) -#endif static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode) { @@ -6188,7 +6259,7 @@ } } -static int ipw_request_scan(struct ipw_priv *priv) +static int ipw_request_scan_helper(struct ipw_priv *priv, int type) { struct ipw_scan_request_ext scan; int err = 0, scan_type; @@ -6219,7 +6290,18 @@ } memset(&scan, 0, sizeof(scan)); + scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); + + if (type == IW_SCAN_TYPE_PASSIVE) { + IPW_DEBUG_WX("use passive scanning\n"); + scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN; + scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = + cpu_to_le16(120); + ipw_add_scan_channels(priv, &scan, scan_type); + goto send_request; + } + /* Use active scan by default. */ if (priv->config & CFG_SPEED_SCAN) scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = cpu_to_le16(30); @@ -6229,9 +6311,8 @@ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = cpu_to_le16(20); - scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); - scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); + scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); #ifdef CONFIG_IPW2200_MONITOR if (priv->ieee->iw_mode == IW_MODE_MONITOR) { @@ -6294,6 +6375,7 @@ } #endif + send_request: err = ipw_send_scan_request_ext(priv, &scan); if (err) { IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); @@ -6309,6 +6391,16 @@ return err; } +static int ipw_request_passive_scan(struct ipw_priv *priv) +{ + return ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); +} + +static int ipw_request_scan(struct ipw_priv *priv) +{ + return ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); +} + static void ipw_bg_abort_scan(void *data) { struct ipw_priv *priv = data; @@ -6387,13 +6480,6 @@ (wrqu->data.length && extra == NULL)) return -EINVAL; - //mutex_lock(&priv->mutex); - - //if (!ieee->wpa_enabled) { - // err = -EOPNOTSUPP; - // goto out; - //} - if (wrqu->data.length) { buf = kmalloc(wrqu->data.length, GFP_KERNEL); if (buf == NULL) { @@ -6413,7 +6499,6 @@ ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); out: - //mutex_unlock(&priv->mutex); return err; } @@ -6426,13 +6511,6 @@ struct ieee80211_device *ieee = priv->ieee; int err = 0; - //mutex_lock(&priv->mutex); - - //if (!ieee->wpa_enabled) { - // err = -EOPNOTSUPP; - // goto out; - //} - if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) { wrqu->data.length = 0; goto out; @@ -6447,7 +6525,6 @@ memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); out: - //mutex_unlock(&priv->mutex); return err; } @@ -6558,7 +6635,6 @@ ieee->ieee802_1x = param->value; break; - //case IW_AUTH_ROAMING_CONTROL: case IW_AUTH_PRIVACY_INVOKED: ieee->privacy_invoked = param->value; break; @@ -6680,7 +6756,7 @@ switch (mlme->cmd) { case IW_MLME_DEAUTH: - // silently ignore + /* silently ignore */ break; case IW_MLME_DISASSOC: @@ -6700,7 +6777,7 @@ * get the modulation type of the current network or * the card current mode */ -static u8 ipw_qos_current_mode(struct ipw_priv * priv) +static u8 ipw_qos_current_mode(struct ipw_priv *priv) { u8 mode = 0; @@ -6848,6 +6925,18 @@ } IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n"); + for (i = 0; i < 3; i++) { + int j; + for (j = 0; j < QOS_QUEUE_NUM; j++) { + qos_parameters[i].cw_min[j] = + cpu_to_le16(qos_parameters[i].cw_min[j]); + qos_parameters[i].cw_max[j] = + cpu_to_le16(qos_parameters[i].cw_max[j]); + qos_parameters[i].tx_op_limit[j] = + cpu_to_le16(qos_parameters[i].tx_op_limit[j]); + } + } + err = ipw_send_qos_params_command(priv, (struct ieee80211_qos_parameters *) &(qos_parameters[0])); @@ -7040,8 +7129,7 @@ return from_priority_to_tx_queue[priority] - 1; } -static int ipw_is_qos_active(struct net_device *dev, - struct sk_buff *skb) +static int ipw_is_qos_active(struct net_device *dev, struct sk_buff *skb) { struct ipw_priv *priv = ieee80211_priv(dev); struct ieee80211_qos_data *qos_data = NULL; @@ -7071,22 +7159,21 @@ return 0; } + /* * add QoS parameter to the TX command */ static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv, - u16 priority, - struct tfd_data *tfd) + u16 priority, struct tfd_data *tfd) { int tx_queue_id = 0; - tx_queue_id = from_priority_to_tx_queue[priority] - 1; tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED; if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) { tfd->tx_flags &= ~DCT_FLAG_ACK_REQD; - tfd->tfd.tfd_26.mchdr.qos_ctrl |= CTRL_QOS_NO_ACK; + tfd->tfd.tfd_26.mchdr.qos_ctrl |= cpu_to_le16(CTRL_QOS_NO_ACK); } return 0; } @@ -7666,8 +7753,8 @@ /* Big bitfield of all the fields we provide in radiotap */ ipw_rt->rt_hdr.it_present = - ((1 << IEEE80211_RADIOTAP_FLAGS) | - (1 << IEEE80211_RADIOTAP_TSFT) | + ((1 << IEEE80211_RADIOTAP_TSFT) | + (1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | @@ -7676,9 +7763,14 @@ /* Zero the flags, we'll add to them as we go */ ipw_rt->rt_flags = 0; + ipw_rt->rt_tsf = (u64) (frame->parent_tsf[3] << 24 | + frame->parent_tsf[2] << 16 | + frame->parent_tsf[1] << 8 | + frame->parent_tsf[0]); /* Convert signal to DBM */ ipw_rt->rt_dbmsignal = antsignal; + ipw_rt->rt_dbmnoise = frame->noise; /* Convert the channel data and set the flags */ ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel)); @@ -7794,7 +7886,6 @@ s8 noise = frame->noise; u8 rate = frame->rate; short len = le16_to_cpu(pkt->u.frame.length); - u64 tsf = 0; struct sk_buff *skb; int hdr_only = 0; u16 filter = priv->prom_priv->filter; @@ -7829,17 +7920,17 @@ } hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE; - if (ieee80211_is_management(hdr->frame_ctl)) { + if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) { if (filter & IPW_PROM_NO_MGMT) return; if (filter & IPW_PROM_MGMT_HEADER_ONLY) hdr_only = 1; - } else if (ieee80211_is_control(hdr->frame_ctl)) { + } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) { if (filter & IPW_PROM_NO_CTL) return; if (filter & IPW_PROM_CTL_HEADER_ONLY) hdr_only = 1; - } else if (ieee80211_is_data(hdr->frame_ctl)) { + } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) { if (filter & IPW_PROM_NO_DATA) return; if (filter & IPW_PROM_DATA_HEADER_ONLY) @@ -7857,7 +7948,7 @@ ipw_rt = (void *)skb->data; if (hdr_only) - len = ieee80211_get_hdrlen(hdr->frame_ctl); + len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); memcpy(ipw_rt->payload, hdr, len); @@ -7879,8 +7970,8 @@ /* Big bitfield of all the fields we provide in radiotap */ ipw_rt->rt_hdr.it_present = - ((1 << IEEE80211_RADIOTAP_FLAGS) | - (1 << IEEE80211_RADIOTAP_TSFT) | + ((1 << IEEE80211_RADIOTAP_TSFT) | + (1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | @@ -7889,8 +7980,10 @@ /* Zero the flags, we'll add to them as we go */ ipw_rt->rt_flags = 0; - - ipw_rt->rt_tsf = tsf; + ipw_rt->rt_tsf = (u64) (frame->parent_tsf[3] << 24 | + frame->parent_tsf[2] << 16 | + frame->parent_tsf[1] << 8 | + frame->parent_tsf[0]); /* Convert to DBM */ ipw_rt->rt_dbmsignal = signal; @@ -7969,7 +8062,7 @@ #endif static int is_network_packet(struct ipw_priv *priv, - struct ieee80211_hdr_4addr *header) + struct ieee80211_hdr_4addr *header) { /* Filter incoming packets to determine if they are targetted toward * this network, discarding packets coming from ourselves */ @@ -8006,8 +8099,8 @@ #define IPW_PACKET_RETRY_TIME HZ -static int is_duplicate_packet(struct ipw_priv *priv, - struct ieee80211_hdr_4addr *header) +static int is_duplicate_packet(struct ipw_priv *priv, + struct ieee80211_hdr_4addr *header) { u16 sc = le16_to_cpu(header->seq_ctl); u16 seq = WLAN_GET_SEQ_SEQ(sc); @@ -8163,8 +8256,7 @@ switch (pkt->header.message_type) { case RX_FRAME_TYPE: /* 802.11 frame */ { struct ieee80211_rx_stats stats = { - .rssi = - le16_to_cpu(pkt->u.frame.rssi_dbm) - + .rssi = pkt->u.frame.rssi_dbm - IPW_RSSI_TO_DBM, .signal = le16_to_cpu(pkt->u.frame.rssi_dbm) - @@ -8195,20 +8287,22 @@ priv->rx_packets++; #ifdef CONFIG_IPW2200_PROMISCUOUS - if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) - ipw_handle_promiscuous_rx(priv, rxb, &stats); + if (priv->prom_net_dev + && netif_running(priv->prom_net_dev)) + ipw_handle_promiscuous_rx(priv, rxb, + &stats); #endif #ifdef CONFIG_IPW2200_MONITOR if (priv->ieee->iw_mode == IW_MODE_MONITOR) { #ifdef CONFIG_IPW2200_RADIOTAP - ipw_handle_data_packet_monitor(priv, - rxb, - &stats); + ipw_handle_data_packet_monitor(priv, + rxb, + &stats); #else - ipw_handle_data_packet(priv, rxb, - &stats); + ipw_handle_data_packet(priv, rxb, + &stats); #endif break; } @@ -8230,16 +8324,18 @@ priv->assoc_network->stats.rssi = stats.rssi; priv->exp_avg_rssi = - exponential_average(priv->exp_avg_rssi, - stats.rssi, DEPTH_RSSI); + exponential_average(priv-> + exp_avg_rssi, + stats.rssi, + DEPTH_RSSI); } IPW_DEBUG_RX("Frame: len=%u\n", le16_to_cpu(pkt->u.frame.length)); if (le16_to_cpu(pkt->u.frame.length) < - ieee80211_get_hdrlen(le16_to_cpu( - header->frame_ctl))) { + ieee80211_get_hdrlen(le16_to_cpu + (header->frame_ctl))) { IPW_DEBUG_DROP ("Received packet is too small. " "Dropping.\n"); @@ -8599,9 +8695,26 @@ * configured CHANNEL then return that; otherwise return ANY */ mutex_lock(&priv->mutex); if (priv->config & CFG_STATIC_CHANNEL || - priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) - wrqu->freq.m = priv->channel; - else + priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) { + int i; + + i = ieee80211_channel_to_index(priv->ieee, priv->channel); + BUG_ON(i == -1); + wrqu->freq.e = 1; + + switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) { + case IEEE80211_52GHZ_BAND: + wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000; + break; + + case IEEE80211_24GHZ_BAND: + wrqu->freq.m = priv->ieee->geo.bg[i].freq * 100000; + break; + + default: + BUG(); + } + } else wrqu->freq.m = 0; mutex_unlock(&priv->mutex); @@ -8776,7 +8890,7 @@ range->event_capa[1] = IW_EVENT_CAPA_K_1; range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; IPW_DEBUG_WX("GET Range\n"); return 0; @@ -8857,42 +8974,37 @@ union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - char *essid = ""; /* ANY */ - int length = 0; + int length; + mutex_lock(&priv->mutex); - if (wrqu->essid.flags && wrqu->essid.length) { - length = wrqu->essid.length - 1; - essid = extra; - } - if (length == 0) { + + if (!wrqu->essid.flags) { IPW_DEBUG_WX("Setting ESSID to ANY\n"); - if ((priv->config & CFG_STATIC_ESSID) && - !(priv->status & (STATUS_ASSOCIATED | - STATUS_ASSOCIATING))) { - IPW_DEBUG_ASSOC("Attempting to associate with new " - "parameters.\n"); - priv->config &= ~CFG_STATIC_ESSID; - ipw_associate(priv); - } + ipw_disassociate(priv); + priv->config &= ~CFG_STATIC_ESSID; + ipw_associate(priv); mutex_unlock(&priv->mutex); return 0; } - length = min(length, IW_ESSID_MAX_SIZE); + length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE); + if (!extra[length - 1]) + length--; priv->config |= CFG_STATIC_ESSID; - if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { + if (priv->essid_len == length && !memcmp(priv->essid, extra, length) + && (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) { IPW_DEBUG_WX("ESSID set to current ESSID.\n"); mutex_unlock(&priv->mutex); return 0; } - IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length), + IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(extra, length), length); priv->essid_len = length; - memcpy(priv->essid, essid, priv->essid_len); + memcpy(priv->essid, extra, priv->essid_len); /* Network configuration changed -- force [re]association */ IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n"); @@ -8962,20 +9074,21 @@ } static int ipw_wx_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); int err = 0; IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value); - IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value); + IPW_DEBUG_WX("Setting disassociate threshold to %d\n", + 3 * wrqu->sens.value); mutex_lock(&priv->mutex); - if (wrqu->sens.fixed == 0) - { + if (wrqu->sens.fixed == 0) { priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT; - priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT; + priv->disassociate_threshold = + IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT; goto out; } if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) || @@ -8985,15 +9098,15 @@ } priv->roaming_threshold = wrqu->sens.value; - priv->disassociate_threshold = 3*wrqu->sens.value; + priv->disassociate_threshold = 3 * wrqu->sens.value; out: mutex_unlock(&priv->mutex); return err; } static int ipw_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); mutex_lock(&priv->mutex); @@ -9273,7 +9386,7 @@ if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) return 0; - if (wrqu->retry.value < 0 || wrqu->retry.value > 255) + if (wrqu->retry.value < 0 || wrqu->retry.value >= 255) return -EINVAL; mutex_lock(&priv->mutex); @@ -9396,17 +9510,20 @@ union iwreq_data *wrqu, char *extra) { struct ipw_priv *priv = ieee80211_priv(dev); - struct iw_scan_req *req = NULL; - if (wrqu->data.length - && wrqu->data.length == sizeof(struct iw_scan_req)) { - req = (struct iw_scan_req *)extra; + struct iw_scan_req *req = (struct iw_scan_req *)extra; + + if (wrqu->data.length == sizeof(struct iw_scan_req)) { if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { ipw_request_direct_scan(priv, req->essid, req->essid_len); return 0; } + if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { + queue_work(priv->workqueue, + &priv->request_passive_scan); + return 0; + } } - IPW_DEBUG_WX("Start scan\n"); queue_work(priv->workqueue, &priv->request_scan); @@ -9766,7 +9886,7 @@ return 0; } -#endif // CONFIG_IPW2200_MONITOR +#endif /* CONFIG_IPW2200_MONITOR */ static int ipw_wx_reset(struct net_device *dev, struct iw_request_info *info, @@ -9991,7 +10115,7 @@ /* net device stuff */ -static void init_sys_config(struct ipw_sys_config *sys_config) +static void init_sys_config(struct ipw_sys_config *sys_config) { memset(sys_config, 0, sizeof(struct ipw_sys_config)); sys_config->bt_coexistence = 0; @@ -10009,7 +10133,7 @@ sys_config->dot11g_auto_detection = 0; sys_config->enable_cts_to_self = 0; sys_config->bt_coexist_collision_thr = 0; - sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256 + sys_config->pass_noise_stats_to_host = 1; /* 1 -- fix for 256 */ sys_config->silence_threshold = 0x1e; } @@ -10040,8 +10164,7 @@ we need to heavily modify the ieee80211_skb_to_txb. */ -static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, - int pri) +static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, int pri) { struct ieee80211_hdr_3addrqos *hdr = (struct ieee80211_hdr_3addrqos *) txb->fragments[0]->data; @@ -10113,7 +10236,7 @@ switch (priv->ieee->sec.level) { case SEC_LEVEL_3: tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= - IEEE80211_FCTL_PROTECTED; + cpu_to_le16(IEEE80211_FCTL_PROTECTED); /* XXX: ACK flag must be set for CCMP even if it * is a multicast/broadcast packet, because CCMP * group communication encrypted by GTK is @@ -10128,14 +10251,14 @@ break; case SEC_LEVEL_2: tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= - IEEE80211_FCTL_PROTECTED; + cpu_to_le16(IEEE80211_FCTL_PROTECTED); tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP; tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP; tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE; break; case SEC_LEVEL_1: tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= - IEEE80211_FCTL_PROTECTED; + cpu_to_le16(IEEE80211_FCTL_PROTECTED); tfd->u.data.key_index = priv->ieee->tx_keyidx; if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <= 40) @@ -10267,24 +10390,24 @@ /* Filtering of fragment chains is done agains the first fragment */ hdr = (void *)txb->fragments[0]->data; - if (ieee80211_is_management(hdr->frame_ctl)) { + if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) { if (filter & IPW_PROM_NO_MGMT) return; if (filter & IPW_PROM_MGMT_HEADER_ONLY) hdr_only = 1; - } else if (ieee80211_is_control(hdr->frame_ctl)) { + } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) { if (filter & IPW_PROM_NO_CTL) return; if (filter & IPW_PROM_CTL_HEADER_ONLY) hdr_only = 1; - } else if (ieee80211_is_data(hdr->frame_ctl)) { + } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) { if (filter & IPW_PROM_NO_DATA) return; if (filter & IPW_PROM_DATA_HEADER_ONLY) hdr_only = 1; } - for(n=0; n<txb->nr_frags; ++n) { + for (n = 0; n < txb->nr_frags; ++n) { struct sk_buff *src = txb->fragments[n]; struct sk_buff *dst; struct ieee80211_radiotap_header *rt_hdr; @@ -10292,35 +10415,35 @@ if (hdr_only) { hdr = (void *)src->data; - len = ieee80211_get_hdrlen(hdr->frame_ctl); + len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); } else len = src->len; - dst = alloc_skb( - len + IEEE80211_RADIOTAP_HDRLEN, GFP_ATOMIC); - if (!dst) continue; + dst = alloc_skb(len + IEEE80211_RADIOTAP_HDRLEN, GFP_ATOMIC); + if (!dst) + continue; rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr)); rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION; rt_hdr->it_pad = 0; - rt_hdr->it_present = 0; /* after all, it's just an idea */ - rt_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL); + rt_hdr->it_present = 0; /* after all, it's just an idea */ + rt_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL); - *(u16*)skb_put(dst, sizeof(u16)) = cpu_to_le16( - ieee80211chan2mhz(priv->channel)); - if (priv->channel > 14) /* 802.11a */ - *(u16*)skb_put(dst, sizeof(u16)) = - cpu_to_le16(IEEE80211_CHAN_OFDM | - IEEE80211_CHAN_5GHZ); - else if (priv->ieee->mode == IEEE_B) /* 802.11b */ - *(u16*)skb_put(dst, sizeof(u16)) = - cpu_to_le16(IEEE80211_CHAN_CCK | - IEEE80211_CHAN_2GHZ); - else /* 802.11g */ - *(u16*)skb_put(dst, sizeof(u16)) = - cpu_to_le16(IEEE80211_CHAN_OFDM | - IEEE80211_CHAN_2GHZ); + *(u16 *) skb_put(dst, sizeof(u16)) = + cpu_to_le16(ieee80211chan2mhz(priv->channel)); + if (priv->channel > 14) /* 802.11a */ + *(u16 *) skb_put(dst, sizeof(u16)) = + cpu_to_le16(IEEE80211_CHAN_OFDM | + IEEE80211_CHAN_5GHZ); + else if (priv->ieee->mode == IEEE_B) /* 802.11b */ + *(u16 *) skb_put(dst, sizeof(u16)) = + cpu_to_le16(IEEE80211_CHAN_CCK | + IEEE80211_CHAN_2GHZ); + else /* 802.11g */ + *(u16 *) skb_put(dst, sizeof(u16)) = + cpu_to_le16(IEEE80211_CHAN_OFDM | + IEEE80211_CHAN_2GHZ); rt_hdr->it_len = dst->len; @@ -10348,7 +10471,6 @@ netif_stop_queue(dev); goto fail_unlock; } - #ifdef CONFIG_IPW2200_PROMISCUOUS if (rtap_iface && netif_running(priv->prom_net_dev)) ipw_handle_promiscuous_tx(priv, txb); @@ -10636,6 +10762,8 @@ INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv); INIT_WORK(&priv->request_scan, (void (*)(void *))ipw_request_scan, priv); + INIT_WORK(&priv->request_passive_scan, + (void (*)(void *))ipw_request_passive_scan, priv); INIT_WORK(&priv->gather_stats, (void (*)(void *))ipw_bg_gather_stats, priv); INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv); @@ -10800,7 +10928,6 @@ priv->sys_config.bt_coexistence |= CFG_BT_COEXISTENCE_OOB; } - #ifdef CONFIG_IPW2200_PROMISCUOUS if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) { priv->sys_config.accept_all_data_frames = 1; @@ -11467,7 +11594,6 @@ #endif - static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0; @@ -11488,9 +11614,7 @@ priv->net_dev = net_dev; priv->pci_dev = pdev; -#ifdef CONFIG_IPW2200_DEBUG ipw_debug_level = debug; -#endif spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->lock); for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) @@ -11598,10 +11733,9 @@ IPW_ERROR("failed to register network device\n"); goto out_remove_sysfs; } - #ifdef CONFIG_IPW2200_PROMISCUOUS if (rtap_iface) { - err = ipw_prom_alloc(priv); + err = ipw_prom_alloc(priv); if (err) { IPW_ERROR("Failed to register promiscuous network " "device (error %d).\n", err); @@ -11755,6 +11910,16 @@ } #endif +static void ipw_pci_shutdown(struct pci_dev *pdev) +{ + struct ipw_priv *priv = pci_get_drvdata(pdev); + + /* Take down the device; powers it off, etc. */ + ipw_down(priv); + + pci_disable_device(pdev); +} + /* driver initialization stuff */ static struct pci_driver ipw_driver = { .name = DRV_NAME, @@ -11765,6 +11932,7 @@ .suspend = ipw_pci_suspend, .resume = ipw_pci_resume, #endif + .shutdown = ipw_pci_shutdown, }; static int __init ipw_init(void) @@ -11808,17 +11978,16 @@ module_param(led, int, 0444); MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); -#ifdef CONFIG_IPW2200_DEBUG module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); -#endif module_param(channel, int, 0444); MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); #ifdef CONFIG_IPW2200_PROMISCUOUS module_param(rtap_iface, int, 0444); -MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)"); +MODULE_PARM_DESC(rtap_iface, + "create the rtap interface (1 - create, default 0)"); #endif #ifdef CONFIG_IPW2200_QOS @@ -11860,7 +12029,8 @@ MODULE_PARM_DESC(roaming, "enable roaming support (default on)"); module_param(antenna, int, 0444); -MODULE_PARM_DESC(antenna, "select antenna 1=Main, 3=Aux, default 0 [both], 2=slow_diversity (choose the one with lower background noise)"); +MODULE_PARM_DESC(antenna, + "select antenna 1=Main, 3=Aux, default 0 [both], 2=slow_diversity (choose the one with lower background noise)"); module_exit(ipw_exit); module_init(ipw_init); -- John W. Linville linville@redhat.com