Commit 6cd15a9d authored by 's avatar Committed by Jeff Garzik

Automatic merge of /spare/repo/netdev-2.6 branch we18-ieee80211

parents ff1d2767 43f66a6c
===========================
Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux
README.ipw2100
March 14, 2005
===========================
Index
---------------------------
0. Introduction
1. Release 1.1.0 Current Features
2. Command Line Parameters
3. Sysfs Helper Files
4. Radio Kill Switch
5. Dynamic Firmware
6. Power Management
7. Support
8. License
===========================
0. Introduction
------------ ----- ----- ---- --- -- -
This document provides a brief overview of the features supported by the
IPW2100 driver project. The main project website, where the latest
development version of the driver can be found, is:
http://ipw2100.sourceforge.net
There you can find the not only the latest releases, but also information about
potential fixes and patches, as well as links to the development mailing list
for the driver project.
===========================
1. Release 1.1.0 Current Supported Features
---------------------------
- Managed (BSS) and Ad-Hoc (IBSS)
- WEP (shared key and open)
- Wireless Tools support
- 802.1x (tested with XSupplicant 1.0.1)
Enabled (but not supported) features:
- Monitor/RFMon mode
- WPA/WPA2
The distinction between officially supported and enabled is a reflection
on the amount of validation and interoperability testing that has been
performed on a given feature.
===========================
2. Command Line Parameters
---------------------------
If the driver is built as a module, the following optional parameters are used
by entering them on the command line with the modprobe command using this
syntax:
modprobe ipw2100 [<option>=<VAL1><,VAL2>...]
For example, to disable the radio on driver loading, enter:
modprobe ipw2100 disable=1
The ipw2100 driver supports the following module parameters:
Name Value Example:
debug 0x0-0xffffffff debug=1024
mode 0,1,2 mode=1 /* AdHoc */
channel int channel=3 /* Only valid in AdHoc or Monitor */
associate boolean associate=0 /* Do NOT auto associate */
disable boolean disable=1 /* Do not power the HW */
===========================
3. Sysfs Helper Files
---------------------------
There are several ways to control the behavior of the driver. Many of the
general capabilities are exposed through the Wireless Tools (iwconfig). There
are a few capabilities that are exposed through entries in the Linux Sysfs.
----- Driver Level ------
For the driver level files, look in /sys/bus/pci/drivers/ipw2100/
debug_level
This controls the same global as the 'debug' module parameter. For
information on the various debugging levels available, run the 'dvals'
script found in the driver source directory.
NOTE: 'debug_level' is only enabled if CONFIG_IPW2100_DEBUG is turn
on.
----- Device Level ------
For the device level files look in
/sys/bus/pci/drivers/ipw2100/{PCI-ID}/
For example:
/sys/bus/pci/drivers/ipw2100/0000:02:01.0
For the device level files, see /sys/bus/pci/drivers/ipw2100:
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
===========================
4. Radio Kill Switch
---------------------------
Most laptops provide the ability for the user to physically disable the radio.
Some vendors have implemented this as a physical switch that requires no
software to turn the radio off and on. On other laptops, however, the switch
is controlled through a button being pressed and a software driver then making
calls to turn the radio off and on. This is referred to as a "software based
RF kill switch"
See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
on your system.
===========================
5. Dynamic Firmware
---------------------------
As the firmware is licensed under a restricted use license, it can not be
included within the kernel sources. To enable the IPW2100 you will need a
firmware image to load into the wireless NIC's processors.
You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
See INSTALL for instructions on installing the firmware.
===========================
6. Power Management
---------------------------
The IPW2100 supports the configuration of the Power Save Protocol
through a private wireless extension interface. The IPW2100 supports
the following different modes:
off No power management. Radio is always on.
on Automatic power management
1-5 Different levels of power management. The higher the
number the greater the power savings, but with an impact to
packet latencies.
Power management works by powering down the radio after a certain
interval of time has passed where no packets are passed through the
radio. Once powered down, the radio remains in that state for a given
period of time. For higher power savings, the interval between last
packet processed to sleep is shorter and the sleep period is longer.
When the radio is asleep, the access point sending data to the station
must buffer packets at the AP until the station wakes up and requests
any buffered packets. If you have an AP that does not correctly support
the PSP protocol you may experience packet loss or very poor performance
while power management is enabled. If this is the case, you will need
to try and find a firmware update for your AP, or disable power
management (via `iwconfig eth1 power off`)
To configure the power level on the IPW2100 you use a combination of
iwconfig and iwpriv. iwconfig is used to turn power management on, off,
and set it to auto.
iwconfig eth1 power off Disables radio power down
iwconfig eth1 power on Enables radio power management to
last set level (defaults to AUTO)
iwpriv eth1 set_power 0 Sets power level to AUTO and enables
power management if not previously
enabled.
iwpriv eth1 set_power 1-5 Set the power level as specified,
enabling power management if not
previously enabled.
You can view the current power level setting via:
iwpriv eth1 get_power
It will return the current period or timeout that is configured as a string
in the form of xxxx/yyyy (z) where xxxx is the timeout interval (amount of
time after packet processing), yyyy is the period to sleep (amount of time to
wait before powering the radio and querying the access point for buffered
packets), and z is the 'power level'. If power management is turned off the
xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
level if `iwconfig eth1 power on` is invoked.
===========================
7. Support
---------------------------
For general development information and support,
go to:
http://ipw2100.sf.net/
The ipw2100 1.1.0 driver and firmware can be downloaded from:
http://support.intel.com
For installation support on the ipw2100 1.1.0 driver on Linux kernels
2.6.8 or greater, email support is available from:
http://supportmail.intel.com
===========================
8. License
---------------------------
Copyright(c) 2003 - 2005 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.
License Contact Information:
James P. Ketrenos <ipw2100-admin@linux.intel.com>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
Intel(R) PRO/Wireless 2915ABG 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 reference the
unified driver.
Copyright (C) 2004-2005, Intel Corporation
README.ipw2200
Version: 1.0.0
Date : January 31, 2005
Index
-----------------------------------------------
1. Introduction
1.1. Overview of features
1.2. Module parameters
1.3. Wireless Extension Private Methods
1.4. Sysfs Helper Files
2. About the Version Numbers
3. Support
4. License
1. Introduction
-----------------------------------------------
The following sections attempt to provide a brief introduction to using
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 driver, see the INSTALL
file.
1.1. Overview of Features
-----------------------------------------------
The current release (1.0.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)
+ long/short preamble support
1.2. Command Line Parameters
-----------------------------------------------
Like many modules used in the Linux kernel, the Intel(R) PRO/Wireless
2915ABG Driver for Linux allows certain configuration options to be
provided as module parameters. The most common way to specify a module
parameter is via the command line.
The general form is:
% modprobe ipw2200 parameter=value
Where the supported parameter are:
associate
Set 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 for the target network, for example configuring
the network SSID. Default is 1 (auto-associate)
Example: % modprobe ipw2200 associate=0
auto_create
Set 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 normal method for setting
the channel would be 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 is logged. See the 'dval' and 'load' script for more info on
how to use this (the dval and load scripts are provided as part
of the ipw2200 development snapshot releases available from the
SourceForge project at http://ipw2200.sf.net)
mode
Can be used to set the default mode of the adapter.
0 = Managed, 1 = Ad-Hoc
1.3. Wireless Extension Private Methods
-----------------------------------------------
As an interface 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_IPW_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 transferring
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 are 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 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
2. 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.1.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 driver. Currently, there are no major changes planned.
3. Support
-----------------------------------------------
For installation 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/
4. License
-----------------------------------------------
Copyright(c) 2003 - 2005 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
...@@ -137,6 +137,111 @@ config PCMCIA_RAYCS ...@@ -137,6 +137,111 @@ config PCMCIA_RAYCS
comment "Wireless 802.11b ISA/PCI cards support" comment "Wireless 802.11b ISA/PCI cards support"
depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA) depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
config IPW2100
tristate "Intel PRO/Wireless 2100 Network Connection"
depends on NET_RADIO && PCI && IEEE80211
select FW_LOADER
---help---
A driver for the Intel PRO/Wireless 2100 Network
Connection 802.11b wireless network adapter.
See <file:Documentation/networking/README.ipw2100> for information on
the capabilities currently enabled in this driver and for tips
for debugging issues and problems.
In order to use this driver, you will need a firmware image for it.
You can obtain the firmware from
<http://ipw2100.sf.net/>. Once you have the firmware image, you
will need to place it in /etc/firmware.
You will also very likely need the Wireless Tools in order to
configure your card:
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
If you want to compile the driver as a module ( = code which can be
inserted in and remvoed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called ipw2100.ko.
config IPW2100_PROMISC
bool "Enable promiscuous mode"
depends on IPW2100
---help---
Enables promiscuous/monitor mode support for the ipw2100 driver.
With this feature compiled into the driver, you can switch to
promiscuous mode via the Wireless Tool's Monitor mode. While in this
mode, no packets can be sent.
config IPW_DEBUG
bool "Enable full debugging output in IPW2100 module."
depends on IPW2100
---help---
This option will enable debug tracing output for the IPW2100.
This will result in the kernel module being ~60k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/bus/pci/drivers/ipw2100/debug_level
This entry will only exist if this option is enabled.
If you are not trying to debug or develop the IPW2100 driver, you
most likely want to say N here.
config IPW2200
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
depends on NET_RADIO && PCI
select FW_LOADER
select IEEE80211
---help---
A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
Connection adapters.
See <file:Documentation/networking/README.ipw2200> for
information on the capabilities currently enabled in this
driver and for tips for debugging issues and problems.
In order to use this driver, you will need a firmware image for it.
You can obtain the firmware from
<http://ipw2200.sf.net/>. See the above referenced README.ipw2200
for information on where to install the firmare images.
You will also very likely need the Wireless Tools in order to
configure your card:
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
If you want to compile the driver as a module ( = code which can be
inserted in and remvoed from the running kernel whenever you want),
say M here and read <file:Documentation/modules.txt>. The module
will be called ipw2200.ko.
config IPW_DEBUG
bool "Enable full debugging output in IPW2200 module."
depends on IPW2200
---help---
This option will enable debug tracing output for the IPW2200.
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/bus/pci/drivers/ipw2200/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
% echo 0x00000FFO > /sys/bus/pci/drivers/ipw2200/debug_level
You can find the list of debug mask values in
drivers/net/wireless/ipw2200.h
If you are not trying to debug or develop the IPW2200 driver, you
most likely want to say N here.
config AIRO config AIRO
tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
depends on NET_RADIO && ISA && (PCI || BROKEN) depends on NET_RADIO && ISA && (PCI || BROKEN)
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
# Makefile for the Linux Wireless network device drivers. # Makefile for the Linux Wireless network device drivers.
# #
obj-$(CONFIG_IPW2100) += ipw2100.o
obj-$(CONFIG_IPW2200) += ipw2200.o
obj-$(CONFIG_STRIP) += strip.o obj-$(CONFIG_STRIP) += strip.o
obj-$(CONFIG_ARLAN) += arlan.o obj-$(CONFIG_ARLAN) += arlan.o
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include "ieee802_11.h" #include <net/ieee80211.h>
#include "atmel.h" #include "atmel.h"
#define DRIVER_MAJOR 0 #define DRIVER_MAJOR 0
...@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv); ...@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv);
static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data); static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
static void atmel_command_irq(struct atmel_private *priv); static void atmel_command_irq(struct atmel_private *priv);
static int atmel_validate_channel(struct atmel_private *priv, int channel); static int atmel_validate_channel(struct atmel_private *priv, int channel);
static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
u16 frame_len, u8 rssi); u16 frame_len, u8 rssi);
static void atmel_management_timer(u_long a); static void atmel_management_timer(u_long a);
static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size); static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size); static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
u8 *body, int body_len); u8 *body, int body_len);
static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index); static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
...@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l ...@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
static int start_tx (struct sk_buff *skb, struct net_device *dev) static int start_tx (struct sk_buff *skb, struct net_device *dev)
{ {
struct atmel_private *priv = netdev_priv(dev); struct atmel_private *priv = netdev_priv(dev);
struct ieee802_11_hdr header; struct ieee80211_hdr header;
unsigned long flags; unsigned long flags;
u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
...@@ -863,17 +863,17 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev) ...@@ -863,17 +863,17 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
return 1; return 1;
} }
frame_ctl = IEEE802_11_FTYPE_DATA; frame_ctl = IEEE80211_FTYPE_DATA;
header.duration_id = 0; header.duration_id = 0;
header.seq_ctl = 0; header.seq_ctl = 0;
if (priv->wep_is_on) if (priv->wep_is_on)
frame_ctl |= IEEE802_11_FCTL_WEP; frame_ctl |= IEEE80211_FCTL_WEP;
if (priv->operating_mode == IW_MODE_ADHOC) { if (priv->operating_mode == IW_MODE_ADHOC) {
memcpy(&header.addr1, skb->data, 6); memcpy(&header.addr1, skb->data, 6);
memcpy(&header.addr2, dev->dev_addr, 6); memcpy(&header.addr2, dev->dev_addr, 6);
memcpy(&header.addr3, priv->BSSID, 6); memcpy(&header.addr3, priv->BSSID, 6);
} else { } else {
frame_ctl |= IEEE802_11_FCTL_TODS; frame_ctl |= IEEE80211_FCTL_TODS;
memcpy(&header.addr1, priv->CurrentBSSID, 6); memcpy(&header.addr1, priv->CurrentBSSID, 6);
memcpy(&header.addr2, dev->dev_addr, 6); memcpy(&header.addr2, dev->dev_addr, 6);
memcpy(&header.addr3, skb->data, 6); memcpy(&header.addr3, skb->data, 6);
...@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev) ...@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
} }
static void atmel_transmit_management_frame(struct atmel_private *priv, static void atmel_transmit_management_frame(struct atmel_private *priv,
struct ieee802_11_hdr *header, struct ieee80211_hdr *header,
u8 *body, int body_len) u8 *body, int body_len)
{ {
u16 buff; u16 buff;
...@@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv, ...@@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT); tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
} }
static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc) u16 msdu_size, u16 rx_packet_loc, u32 crc)
{ {
/* fast path: unfragmented packet copy directly into skbuf */ /* fast path: unfragmented packet copy directly into skbuf */
...@@ -955,7 +955,7 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head ...@@ -955,7 +955,7 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head
} }
memcpy(skbp, header->addr1, 6); /* destination address */ memcpy(skbp, header->addr1, 6); /* destination address */
if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
memcpy(&skbp[6], header->addr3, 6); memcpy(&skbp[6], header->addr3, 6);
else else
memcpy(&skbp[6], header->addr2, 6); /* source address */ memcpy(&skbp[6], header->addr2, 6); /* source address */
...@@ -990,14 +990,14 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size) ...@@ -990,14 +990,14 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
return (crc ^ 0xffffffff) == netcrc; return (crc ^ 0xffffffff) == netcrc;
} }
static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags) u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
{ {
u8 mac4[6]; u8 mac4[6];
u8 source[6]; u8 source[6];
struct sk_buff *skb; struct sk_buff *skb;
if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
memcpy(source, header->addr3, 6); memcpy(source, header->addr3, 6);
else else
memcpy(source, header->addr2, 6); memcpy(source, header->addr2, 6);
...@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head ...@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head
static void rx_done_irq(struct atmel_private *priv) static void rx_done_irq(struct atmel_private *priv)
{ {
int i; int i;
struct ieee802_11_hdr header; struct ieee80211_hdr header;
for (i = 0; for (i = 0;
atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID && atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
...@@ -1117,7 +1117,7 @@ static void rx_done_irq(struct atmel_private *priv) ...@@ -1117,7 +1117,7 @@ static void rx_done_irq(struct atmel_private *priv)
/* probe for CRC use here if needed once five packets have arrived with /* probe for CRC use here if needed once five packets have arrived with
the same crc status, we assume we know what's happening and stop probing */ the same crc status, we assume we know what's happening and stop probing */
if (priv->probe_crc) { if (priv->probe_crc) {
if (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP)) { if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_WEP)) {
priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size); priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
} else { } else {
priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24); priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
...@@ -1132,16 +1132,16 @@ static void rx_done_irq(struct atmel_private *priv) ...@@ -1132,16 +1132,16 @@ static void rx_done_irq(struct atmel_private *priv)
} }
/* don't CRC header when WEP in use */ /* don't CRC header when WEP in use */
if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP))) { if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_WEP))) {
crc = crc32_le(0xffffffff, (unsigned char *)&header, 24); crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
} }
msdu_size -= 24; /* header */ msdu_size -= 24; /* header */
if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_DATA) { if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
int more_fragments = frame_ctl & IEEE802_11_FCTL_MOREFRAGS; int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
u8 packet_fragment_no = seq_control & IEEE802_11_SCTL_FRAG; u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
u16 packet_sequence_no = (seq_control & IEEE802_11_SCTL_SEQ) >> 4; u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
if (!more_fragments && packet_fragment_no == 0 ) { if (!more_fragments && packet_fragment_no == 0 ) {
fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc); fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
...@@ -1151,7 +1151,7 @@ static void rx_done_irq(struct atmel_private *priv) ...@@ -1151,7 +1151,7 @@ static void rx_done_irq(struct atmel_private *priv)
} }
} }
if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_MGMT) { if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
/* copy rest of packet into buffer */ /* copy rest of packet into buffer */
atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size); atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
...@@ -2663,10 +2663,10 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c ...@@ -2663,10 +2663,10 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len) static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
{ {
struct ieee802_11_hdr header; struct ieee80211_hdr header;
struct auth_body auth; struct auth_body auth;
header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | IEEE802_11_STYPE_AUTH); header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
header.duration_id = cpu_to_le16(0x8000); header.duration_id = cpu_to_le16(0x8000);
header.seq_ctl = 0; header.seq_ctl = 0;
memcpy(header.addr1, priv->CurrentBSSID, 6); memcpy(header.addr1, priv->CurrentBSSID, 6);
...@@ -2677,7 +2677,7 @@ static void send_authentication_request(struct atmel_private *priv, u8 *challeng ...@@ -2677,7 +2677,7 @@ static void send_authentication_request(struct atmel_private *priv, u8 *challeng
auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY); auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY);
/* no WEP for authentication frames with TrSeqNo 1 */ /* no WEP for authentication frames with TrSeqNo 1 */
if (priv->CurrentAuthentTransactionSeqNum != 1) if (priv->CurrentAuthentTransactionSeqNum != 1)
header.frame_ctl |= cpu_to_le16(IEEE802_11_FCTL_WEP); header.frame_ctl |= cpu_to_le16(IEEE80211_FCTL_WEP);
} else { } else {
auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM); auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
} }
...@@ -2701,7 +2701,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) ...@@ -2701,7 +2701,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
{ {
u8 *ssid_el_p; u8 *ssid_el_p;
int bodysize; int bodysize;
struct ieee802_11_hdr header; struct ieee80211_hdr header;
struct ass_req_format { struct ass_req_format {
u16 capability; u16 capability;
u16 listen_interval; u16 listen_interval;
...@@ -2714,8 +2714,8 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) ...@@ -2714,8 +2714,8 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
u8 rates[4]; u8 rates[4];
} body; } body;
header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
(is_reassoc ? IEEE802_11_STYPE_REASSOC_REQ : IEEE802_11_STYPE_ASSOC_REQ)); (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
header.duration_id = cpu_to_le16(0x8000); header.duration_id = cpu_to_le16(0x8000);
header.seq_ctl = 0; header.seq_ctl = 0;
...@@ -2751,9 +2751,9 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) ...@@ -2751,9 +2751,9 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize); atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
} }
static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee802_11_hdr *header) static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
{ {
if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0; return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
else else
return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0; return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
...@@ -2801,7 +2801,7 @@ static int retrieve_bss(struct atmel_private *priv) ...@@ -2801,7 +2801,7 @@ static int retrieve_bss(struct atmel_private *priv)
} }
static void store_bss_info(struct atmel_private *priv, struct ieee802_11_hdr *header, static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
u16 capability, u16 beacon_period, u8 channel, u8 rssi, u16 capability, u16 beacon_period, u8 channel, u8 rssi,
u8 ssid_len, u8 *ssid, int is_beacon) u8 ssid_len, u8 *ssid, int is_beacon)
{ {
...@@ -3085,12 +3085,12 @@ static void atmel_smooth_qual(struct atmel_private *priv) ...@@ -3085,12 +3085,12 @@ static void atmel_smooth_qual(struct atmel_private *priv)
} }
/* deals with incoming managment frames. */ /* deals with incoming managment frames. */
static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
u16 frame_len, u8 rssi) u16 frame_len, u8 rssi)
{ {
u16 subtype; u16 subtype;
switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_STYPE) { switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE) {
case C80211_SUBTYPE_MGMT_BEACON : case C80211_SUBTYPE_MGMT_BEACON :
case C80211_SUBTYPE_MGMT_ProbeResponse: case C80211_SUBTYPE_MGMT_ProbeResponse:
......
#ifndef _IEEE802_11_H
#define _IEEE802_11_H
#define IEEE802_11_DATA_LEN 2304
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6.2.1.1.2.
The figure in section 7.1.2 suggests a body size of up to 2312
bytes is allowed, which is a bit confusing, I suspect this
represents the 2304 bytes of real data, plus a possible 8 bytes of
WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
#define IEEE802_11_HLEN 30
#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
struct ieee802_11_hdr {
u16 frame_ctl;
u16 duration_id;
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
u8 addr3[ETH_ALEN];
u16 seq_ctl;
u8 addr4[ETH_ALEN];
} __attribute__ ((packed));
/* Frame control field constants */
#define IEEE802_11_FCTL_VERS 0x0002
#define IEEE802_11_FCTL_FTYPE 0x000c
#define IEEE802_11_FCTL_STYPE 0x00f0
#define IEEE802_11_FCTL_TODS 0x0100
#define IEEE802_11_FCTL_FROMDS 0x0200
#define IEEE802_11_FCTL_MOREFRAGS 0x0400
#define IEEE802_11_FCTL_RETRY 0x0800
#define IEEE802_11_FCTL_PM 0x1000
#define IEEE802_11_FCTL_MOREDATA 0x2000
#define IEEE802_11_FCTL_WEP 0x4000
#define IEEE802_11_FCTL_ORDER 0x8000
#define IEEE802_11_FTYPE_MGMT 0x0000
#define IEEE802_11_FTYPE_CTL 0x0004
#define IEEE802_11_FTYPE_DATA 0x0008
/* management */
#define IEEE802_11_STYPE_ASSOC_REQ 0x0000
#define IEEE802_11_STYPE_ASSOC_RESP 0x0010
#define IEEE802_11_STYPE_REASSOC_REQ 0x0020
#define IEEE802_11_STYPE_REASSOC_RESP 0x0030
#define IEEE802_11_STYPE_PROBE_REQ 0x0040
#define IEEE802_11_STYPE_PROBE_RESP 0x0050
#define IEEE802_11_STYPE_BEACON 0x0080
#define IEEE802_11_STYPE_ATIM 0x0090
#define IEEE802_11_STYPE_DISASSOC 0x00A0
#define IEEE802_11_STYPE_AUTH 0x00B0
#define IEEE802_11_STYPE_DEAUTH 0x00C0
/* control */
#define IEEE802_11_STYPE_PSPOLL 0x00A0
#define IEEE802_11_STYPE_RTS 0x00B0
#define IEEE802_11_STYPE_CTS 0x00C0
#define IEEE802_11_STYPE_ACK 0x00D0
#define IEEE802_11_STYPE_CFEND 0x00E0
#define IEEE802_11_STYPE_CFENDACK 0x00F0
/* data */
#define IEEE802_11_STYPE_DATA 0x0000
#define IEEE802_11_STYPE_DATA_CFACK 0x0010
#define IEEE802_11_STYPE_DATA_CFPOLL 0x0020
#define IEEE802_11_STYPE_DATA_CFACKPOLL 0x0030
#define IEEE802_11_STYPE_NULLFUNC 0x0040
#define IEEE802_11_STYPE_CFACK 0x0050
#define IEEE802_11_STYPE_CFPOLL 0x0060
#define IEEE802_11_STYPE_CFACKPOLL 0x0070
#define IEEE802_11_SCTL_FRAG 0x000F
#define IEEE802_11_SCTL_SEQ 0xFFF0
#endif /* _IEEE802_11_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -464,6 +464,8 @@ ...@@ -464,6 +464,8 @@
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include <net/ieee80211.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -471,7 +473,6 @@ ...@@ -471,7 +473,6 @@
#include "hermes.h" #include "hermes.h"
#include "hermes_rid.h" #include "hermes_rid.h"
#include "orinoco.h" #include "orinoco.h"
#include "ieee802_11.h"
/********************************************************************/ /********************************************************************/
/* Module information */ /* Module information */
...@@ -509,7 +510,7 @@ MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes"); ...@@ -509,7 +510,7 @@ MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
/********************************************************************/ /********************************************************************/
#define ORINOCO_MIN_MTU 256 #define ORINOCO_MIN_MTU 256
#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD) #define ORINOCO_MAX_MTU (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD)
#define SYMBOL_MAX_VER_LEN (14) #define SYMBOL_MAX_VER_LEN (14)
#define USER_BAP 0 #define USER_BAP 0
...@@ -760,7 +761,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu) ...@@ -760,7 +761,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) ) if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
return -EINVAL; return -EINVAL;
if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) > if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) >
(priv->nicbuf_size - ETH_HLEN) ) (priv->nicbuf_size - ETH_HLEN) )
return -EINVAL; return -EINVAL;
...@@ -1104,7 +1105,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) ...@@ -1104,7 +1105,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
stats->rx_dropped++; stats->rx_dropped++;
goto drop; goto drop;
} }
if (length > IEEE802_11_DATA_LEN) { if (length > IEEE80211_DATA_LEN) {
printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n", printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
dev->name, length); dev->name, length);
stats->rx_length_errors++; stats->rx_length_errors++;
...@@ -2264,7 +2265,7 @@ static int orinoco_init(struct net_device *dev) ...@@ -2264,7 +2265,7 @@ static int orinoco_init(struct net_device *dev)
/* No need to lock, the hw_unavailable flag is already set in /* No need to lock, the hw_unavailable flag is already set in
* alloc_orinocodev() */ * alloc_orinocodev() */
priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
/* Initialize the firmware */ /* Initialize the firmware */
err = hermes_init(hw); err = hermes_init(hw);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define __WL3501_H__ #define __WL3501_H__
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include "ieee802_11.h" #include <net/ieee80211.h>
/* define for WLA 2.0 */ /* define for WLA 2.0 */
#define WL3501_BLKSZ 256 #define WL3501_BLKSZ 256
...@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr { ...@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
struct wl3501_80211_tx_hdr { struct wl3501_80211_tx_hdr {
struct wl3501_80211_tx_plcp_hdr pclp_hdr; struct wl3501_80211_tx_plcp_hdr pclp_hdr;
struct ieee802_11_hdr mac_hdr; struct ieee80211_hdr mac_hdr;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* /*
......
This diff is collapsed.
This diff is collapsed.
/*
* Original code based on Host AP (software wireless LAN access point) driver
* for Intersil Prism2/2.5/3.
*
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <jkmaline@cc.hut.fi>
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
*
* Adaption to a generic IEEE 802.11 stack by James Ketrenos
* <jketreno@linux.intel.com>
*
* Copyright (c) 2004, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*/
/*
* This file defines the interface to the ieee80211 crypto module.
*/
#ifndef IEEE80211_CRYPT_H
#define IEEE80211_CRYPT_H
#include <linux/skbuff.h>
struct ieee80211_crypto_ops {
const char *name;
/* init new crypto context (e.g., allocate private data space,
* select IV, etc.); returns NULL on failure or pointer to allocated
* private data on success */
void * (*init)(int keyidx);
/* deinitialize crypto context and free allocated private data */
void (*deinit)(void *priv);
/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
* value from decrypt_mpdu is passed as the keyidx value for
* decrypt_msdu. skb must have enough head and tail room for the
* encryption; if not, error will be returned; these functions are
* called for all MPDUs (i.e., fragments).
*/
int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
/* These functions are called for full MSDUs, i.e. full frames.
* These can be NULL if full MSDU operations are not needed. */
int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
void *priv);
int (*set_key)(void *key, int len, u8 *seq, void *priv);
int (*get_key)(void *key, int len, u8 *seq, void *priv);
/* procfs handler for printing out key information and possible
* statistics */
char * (*print_stats)(char *p, void *priv);
/* maximum number of bytes added by encryption; encrypt buf is
* allocated with extra_prefix_len bytes, copy of in_buf, and
* extra_postfix_len; encrypt need not use all this space, but
* the result must start at the beginning of the buffer and correct
* length must be returned */
int extra_prefix_len, extra_postfix_len;
struct module *owner;
};
struct ieee80211_crypt_data {
struct list_head list; /* delayed deletion list */
struct ieee80211_crypto_ops *ops;
void *priv;
atomic_t refcnt;
};
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
void ieee80211_crypt_deinit_handler(unsigned long);
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt);
#endif
...@@ -640,6 +640,8 @@ source "net/irda/Kconfig" ...@@ -640,6 +640,8 @@ source "net/irda/Kconfig"
source "net/bluetooth/Kconfig" source "net/bluetooth/Kconfig"
source "net/ieee80211/Kconfig"
source "drivers/net/Kconfig" source "drivers/net/Kconfig"
endmenu endmenu
......
...@@ -42,6 +42,7 @@ obj-$(CONFIG_DECNET) += decnet/ ...@@ -42,6 +42,7 @@ obj-$(CONFIG_DECNET) += decnet/
obj-$(CONFIG_ECONET) += econet/ obj-$(CONFIG_ECONET) += econet/
obj-$(CONFIG_VLAN_8021Q) += 8021q/ obj-$(CONFIG_VLAN_8021Q) += 8021q/
obj-$(CONFIG_IP_SCTP) += sctp/ obj-$(CONFIG_IP_SCTP) += sctp/
obj-$(CONFIG_IEEE80211) += ieee80211/
ifeq ($(CONFIG_NET),y) ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o obj-$(CONFIG_SYSCTL) += sysctl_net.o
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* This file implement the Wireless Extensions APIs. * This file implement the Wireless Extensions APIs.
* *
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved. * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
* *
* (As all part of the Linux kernel, this file is GPL) * (As all part of the Linux kernel, this file is GPL)
*/ */
...@@ -187,6 +187,12 @@ static const struct iw_ioctl_description standard_ioctl[] = { ...@@ -187,6 +187,12 @@ static const struct iw_ioctl_description standard_ioctl[] = {
.header_type = IW_HEADER_TYPE_ADDR, .header_type = IW_HEADER_TYPE_ADDR,
.flags = IW_DESCR_FLAG_DUMP, .flags = IW_DESCR_FLAG_DUMP,
}, },
[SIOCSIWMLME - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_mlme),
.max_tokens = sizeof(struct iw_mlme),
},
[SIOCGIWAPLIST - SIOCIWFIRST] = { [SIOCGIWAPLIST - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT, .header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct sockaddr) + .token_size = sizeof(struct sockaddr) +
...@@ -195,7 +201,10 @@ static const struct iw_ioctl_description standard_ioctl[] = { ...@@ -195,7 +201,10 @@ static const struct iw_ioctl_description standard_ioctl[] = {
.flags = IW_DESCR_FLAG_NOMAX, .flags = IW_DESCR_FLAG_NOMAX,
}, },
[SIOCSIWSCAN - SIOCIWFIRST] = { [SIOCSIWSCAN - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM, .header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = 0,
.max_tokens = sizeof(struct iw_scan_req),
}, },
[SIOCGIWSCAN - SIOCIWFIRST] = { [SIOCGIWSCAN - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT, .header_type = IW_HEADER_TYPE_POINT,
...@@ -273,6 +282,42 @@ static const struct iw_ioctl_description standard_ioctl[] = { ...@@ -273,6 +282,42 @@ static const struct iw_ioctl_description standard_ioctl[] = {
[SIOCGIWPOWER - SIOCIWFIRST] = { [SIOCGIWPOWER - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM, .header_type = IW_HEADER_TYPE_PARAM,
}, },
[SIOCSIWGENIE - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[SIOCGIWGENIE - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[SIOCSIWAUTH - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
[SIOCGIWAUTH - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
[SIOCSIWENCODEEXT - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_encode_ext),
.max_tokens = sizeof(struct iw_encode_ext) +
IW_ENCODING_TOKEN_MAX,
},
[SIOCGIWENCODEEXT - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_encode_ext),
.max_tokens = sizeof(struct iw_encode_ext) +
IW_ENCODING_TOKEN_MAX,
},
[SIOCSIWPMKSA - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_pmksa),
.max_tokens = sizeof(struct iw_pmksa),
},
}; };
static const int standard_ioctl_num = (sizeof(standard_ioctl) / static const int standard_ioctl_num = (sizeof(standard_ioctl) /
sizeof(struct iw_ioctl_description)); sizeof(struct iw_ioctl_description));
...@@ -299,6 +344,31 @@ static const struct iw_ioctl_description standard_event[] = { ...@@ -299,6 +344,31 @@ static const struct iw_ioctl_description standard_event[] = {
[IWEVEXPIRED - IWEVFIRST] = { [IWEVEXPIRED - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_ADDR, .header_type = IW_HEADER_TYPE_ADDR,
}, },
[IWEVGENIE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[IWEVMICHAELMICFAILURE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_michaelmicfailure),
},
[IWEVASSOCREQIE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[IWEVASSOCRESPIE - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
[IWEVPMKIDCAND - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_pmkid_cand),
},
}; };
static const int standard_event_num = (sizeof(standard_event) / static const int standard_event_num = (sizeof(standard_event) /
sizeof(struct iw_ioctl_description)); sizeof(struct iw_ioctl_description));
......
config IEEE80211
tristate "Generic IEEE 802.11 Networking Stack"
select NET_RADIO
---help---
This option enables the hardware independent IEEE 802.11
networking stack.
config IEEE80211_DEBUG
bool "Enable full debugging output"
depends on IEEE80211
---help---
This option will enable debug tracing output for the
ieee80211 network stack.
This will result in the kernel module being ~70k larger. You
can control which debug output is sent to the kernel log by
setting the value in
/proc/net/ieee80211/debug_level
For example:
% echo 0x00000FFO > /proc/net/ieee80211/debug_level
For a list of values you can assign to debug_level, you
can look at the bit mask values in <net/ieee80211.h>
If you are not trying to debug or develop the ieee80211
subsystem, you most likely want to say N here.
config IEEE80211_CRYPT_WEP
tristate "IEEE 802.11 WEP encryption (802.1x)"
depends on IEEE80211
select CRYPTO
select CRYPTO_ARC4
select CRC32
---help---
Include software based cipher suites in support of IEEE
802.11's WEP. This is needed for WEP as well as 802.1x.
This can be compiled as a modules and it will be called
"ieee80211_crypt_wep".
config IEEE80211_CRYPT_CCMP
tristate "IEEE 802.11i CCMP support"
depends on IEEE80211
select CRYPTO_AES
---help---
Include software based cipher suites in support of IEEE 802.11i
(aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with CCMP enabled
networks.
This can be compiled as a modules and it will be called
"ieee80211_crypt_ccmp".
config IEEE80211_CRYPT_TKIP
tristate "IEEE 802.11i TKIP encryption"
depends on IEEE80211
select CRYPTO_MICHAEL_MIC
---help---
Include software based cipher suites in support of IEEE 802.11i
(aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
networks.
This can be compiled as a modules and it will be called
"ieee80211_crypt_tkip".
obj-$(CONFIG_IEEE80211) += ieee80211.o
obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o
obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o
obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o
obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o
ieee80211-objs := \
ieee80211_module.o \
ieee80211_tx.o \
ieee80211_rx.o \
ieee80211_wx.o
/*
* Host AP crypto routines
*
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
* Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
*
* 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. See README and COPYING for
* more details.
*
*/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/string.h>
#include <asm/errno.h>
#include <net/ieee80211.h>
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("HostAP crypto");
MODULE_LICENSE("GPL");
struct ieee80211_crypto_alg {
struct list_head list;
struct ieee80211_crypto_ops *ops;
};
struct ieee80211_crypto {
struct list_head algs;
spinlock_t lock;
};
static struct ieee80211_crypto *hcrypt;
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
int force)
{
struct list_head *ptr, *n;
struct ieee80211_crypt_data *entry;
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
if (atomic_read(&entry->refcnt) != 0 && !force)
continue;
list_del(ptr);
if (entry->ops) {
entry->ops->deinit(entry->priv);
module_put(entry->ops->owner);
}
kfree(entry);
}
}
void ieee80211_crypt_deinit_handler(unsigned long data)
{
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
unsigned long flags;
spin_lock_irqsave(&ieee->lock, flags);
ieee80211_crypt_deinit_entries(ieee, 0);
if (!list_empty(&ieee->crypt_deinit_list)) {
printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
"deletion list\n", ieee->dev->name);
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt)
{
struct ieee80211_crypt_data *tmp;
unsigned long flags;
if (*crypt == NULL)
return;
tmp = *crypt;
*crypt = NULL;
/* must not run ops->deinit() while there may be pending encrypt or
* decrypt operations. Use a list of delayed deinits to avoid needing
* locking. */
spin_lock_irqsave(&ieee->lock, flags);
list_add(&tmp->list, &ieee->crypt_deinit_list);
if (!timer_pending(&ieee->crypt_deinit_timer)) {
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
{
unsigned long flags;
struct ieee80211_crypto_alg *alg;
if (hcrypt == NULL)
return -1;
alg = kmalloc(sizeof(*alg), GFP_KERNEL);
if (alg == NULL)
return -ENOMEM;
memset(alg, 0, sizeof(*alg));
alg->ops = ops;
spin_lock_irqsave(&hcrypt->lock, flags);
list_add(&alg->list, &hcrypt->algs);
spin_unlock_irqrestore(&hcrypt->lock, flags);
printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
ops->name);
return 0;
}
int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
{
unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *del_alg = NULL;
if (hcrypt == NULL)
return -1;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
if (alg->ops == ops) {
list_del(&alg->list);
del_alg = alg;
break;
}
}
spin_unlock_irqrestore(&hcrypt->lock, flags);
if (del_alg) {
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
"'%s'\n", ops->name);
kfree(del_alg);
}
return del_alg ? 0 : -1;
}
struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
{
unsigned long flags;
struct list_head *ptr;
struct ieee80211_crypto_alg *found_alg = NULL;
if (hcrypt == NULL)
return NULL;
spin_lock_irqsave(&hcrypt->lock, flags);
for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
if (strcmp(alg->ops->name, name) == 0) {
found_alg = alg;
break;
}
}
spin_unlock_irqrestore(&hcrypt->lock, flags);
if (found_alg)
return found_alg->ops;
else
return NULL;
}
static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
static void ieee80211_crypt_null_deinit(void *priv) {}
static struct ieee80211_crypto_ops ieee80211_crypt_null = {
.name = "NULL",
.init = ieee80211_crypt_null_init,
.deinit = ieee80211_crypt_null_deinit,
.encrypt_mpdu = NULL,
.decrypt_mpdu = NULL,
.encrypt_msdu = NULL,
.decrypt_msdu = NULL,
.set_key = NULL,
.get_key = NULL,
.extra_prefix_len = 0,
.extra_postfix_len = 0,
.owner = THIS_MODULE,
};
static int __init ieee80211_crypto_init(void)
{
int ret = -ENOMEM;
hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
if (!hcrypt)
goto out;
memset(hcrypt, 0, sizeof(*hcrypt));
INIT_LIST_HEAD(&hcrypt->algs);
spin_lock_init(&hcrypt->lock);
ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
if (ret < 0) {
kfree(hcrypt);
hcrypt = NULL;
}
out:
return ret;
}
static void __exit ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
if (hcrypt == NULL)
return;
for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
ptr = n, n = ptr->next) {
struct ieee80211_crypto_alg *alg =
(struct ieee80211_crypto_alg *) ptr;
list_del(ptr);
printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
"'%s' (deinit)\n", alg->ops->name);
kfree(alg);
}
kfree(hcrypt);
}
EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
EXPORT_SYMBOL(ieee80211_register_crypto_ops);
EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
EXPORT_SYMBOL(ieee80211_get_crypto_ops);
module_init(ieee80211_crypto_init);
module_exit(ieee80211_crypto_deinit);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment