File linux-2.6-wireless-ipw2200-1_2_0-update.patch of Package kernel
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