2005-05-12 22:48:20 -04:00
/*******************************************************************************
2005-09-21 11:58:43 -05:00
Copyright ( c ) 2004 - 2005 Intel Corporation . All rights reserved .
2005-05-12 22:48:20 -04:00
Portions of this file are based on the WEP enablement code provided by the
Host AP project hostap - drivers v0 .1 .3
Copyright ( c ) 2001 - 2002 , SSH Communications Security Corp and Jouni Malinen
2007-03-24 17:15:30 -07:00
< j @ w1 . fi >
Copyright ( c ) 2002 - 2003 , Jouni Malinen < j @ w1 . fi >
2005-05-12 22:48:20 -04:00
This program is free software ; you can redistribute it and / or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation .
This program is distributed in the hope that it will be useful , but WITHOUT
ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
more details .
You should have received a copy of the GNU General Public License along with
this program ; if not , write to the Free Software Foundation , Inc . , 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 :
2009-08-21 13:34:26 -07:00
Intel Linux Wireless < ilw @ linux . intel . com >
2005-05-12 22:48:20 -04:00
Intel Corporation , 5200 N . E . Elam Young Parkway , Hillsboro , OR 97124 - 6497
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <linux/compiler.h>
# include <linux/errno.h>
# include <linux/if_arp.h>
# include <linux/in6.h>
# include <linux/in.h>
# include <linux/ip.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/netdevice.h>
# include <linux/proc_fs.h>
# include <linux/skbuff.h>
# include <linux/slab.h>
# include <linux/tcp.h>
# include <linux/types.h>
# include <linux/wireless.h>
# include <linux/etherdevice.h>
# include <asm/uaccess.h>
2007-09-12 12:01:34 +02:00
# include <net/net_namespace.h>
2005-05-12 22:48:20 -04:00
# include <net/arp.h>
2009-08-20 14:48:03 -04:00
# include "libipw.h"
2005-05-12 22:48:20 -04:00
2005-09-21 11:58:46 -05:00
# define DRV_DESCRIPTION "802.11 data / management / control stack"
2010-03-12 00:01:22 -05:00
# define DRV_NAME "libipw"
2010-11-05 18:57:04 -07:00
# define DRV_PROCNAME "ieee80211"
2009-08-20 14:48:03 -04:00
# define DRV_VERSION LIBIPW_VERSION
2005-09-21 11:58:46 -05:00
# define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
MODULE_VERSION ( DRV_VERSION ) ;
MODULE_DESCRIPTION ( DRV_DESCRIPTION ) ;
MODULE_AUTHOR ( DRV_COPYRIGHT ) ;
2005-05-12 22:48:20 -04:00
MODULE_LICENSE ( " GPL " ) ;
2010-07-20 14:14:03 -04:00
static struct cfg80211_ops libipw_config_ops = { } ;
static void * libipw_wiphy_privid = & libipw_wiphy_privid ;
2009-08-25 14:12:25 -04:00
2009-08-20 14:48:03 -04:00
static int libipw_networks_allocate ( struct libipw_device * ieee )
2005-05-12 22:48:20 -04:00
{
2010-03-08 13:18:03 +08:00
int i , j ;
for ( i = 0 ; i < MAX_NETWORK_COUNT ; i + + ) {
ieee - > networks [ i ] = kzalloc ( sizeof ( struct libipw_network ) ,
GFP_KERNEL ) ;
if ( ! ieee - > networks [ i ] ) {
LIBIPW_ERROR ( " Out of memory allocating beacons \n " ) ;
for ( j = 0 ; j < i ; j + + )
kfree ( ieee - > networks [ j ] ) ;
return - ENOMEM ;
}
2005-05-12 22:48:20 -04:00
}
return 0 ;
}
2009-08-20 14:48:03 -04:00
void libipw_network_reset ( struct libipw_network * network )
2006-01-19 16:21:35 +08:00
{
if ( ! network )
return ;
if ( network - > ibss_dfs ) {
kfree ( network - > ibss_dfs ) ;
network - > ibss_dfs = NULL ;
}
}
2009-08-20 14:48:03 -04:00
static inline void libipw_networks_free ( struct libipw_device * ieee )
2005-05-12 22:48:20 -04:00
{
2006-01-19 16:21:35 +08:00
int i ;
2010-03-08 13:18:03 +08:00
for ( i = 0 ; i < MAX_NETWORK_COUNT ; i + + ) {
2014-06-28 14:18:52 +02:00
kfree ( ieee - > networks [ i ] - > ibss_dfs ) ;
2010-03-08 13:18:03 +08:00
kfree ( ieee - > networks [ i ] ) ;
}
2005-05-12 22:48:20 -04:00
}
2009-08-20 14:48:03 -04:00
void libipw_networks_age ( struct libipw_device * ieee ,
2009-02-11 13:26:06 -05:00
unsigned long age_secs )
{
2009-08-20 14:48:03 -04:00
struct libipw_network * network = NULL ;
2009-02-11 13:26:06 -05:00
unsigned long flags ;
unsigned long age_jiffies = msecs_to_jiffies ( age_secs * MSEC_PER_SEC ) ;
spin_lock_irqsave ( & ieee - > lock , flags ) ;
list_for_each_entry ( network , & ieee - > network_list , list ) {
network - > last_scanned - = age_jiffies ;
}
spin_unlock_irqrestore ( & ieee - > lock , flags ) ;
}
2009-08-20 14:48:03 -04:00
EXPORT_SYMBOL ( libipw_networks_age ) ;
2009-02-11 13:26:06 -05:00
2009-08-20 14:48:03 -04:00
static void libipw_networks_initialize ( struct libipw_device * ieee )
2005-05-12 22:48:20 -04:00
{
int i ;
INIT_LIST_HEAD ( & ieee - > network_free_list ) ;
INIT_LIST_HEAD ( & ieee - > network_list ) ;
for ( i = 0 ; i < MAX_NETWORK_COUNT ; i + + )
2010-03-08 13:18:03 +08:00
list_add_tail ( & ieee - > networks [ i ] - > list ,
2005-09-07 00:48:31 -04:00
& ieee - > network_free_list ) ;
2005-05-12 22:48:20 -04:00
}
2009-08-20 14:48:03 -04:00
int libipw_change_mtu ( struct net_device * dev , int new_mtu )
2006-09-28 19:57:25 +02:00
{
2009-08-20 14:48:03 -04:00
if ( ( new_mtu < 68 ) | | ( new_mtu > LIBIPW_DATA_LEN ) )
2006-09-28 19:57:25 +02:00
return - EINVAL ;
dev - > mtu = new_mtu ;
return 0 ;
}
2009-08-20 14:48:03 -04:00
EXPORT_SYMBOL ( libipw_change_mtu ) ;
2006-09-28 19:57:25 +02:00
2010-03-12 00:01:22 -05:00
struct net_device * alloc_libipw ( int sizeof_priv , int monitor )
2005-05-12 22:48:20 -04:00
{
2009-08-20 14:48:03 -04:00
struct libipw_device * ieee ;
2005-05-12 22:48:20 -04:00
struct net_device * dev ;
int err ;
2009-08-20 14:48:03 -04:00
LIBIPW_DEBUG_INFO ( " Initializing... \n " ) ;
2005-05-12 22:48:20 -04:00
2009-08-20 14:48:03 -04:00
dev = alloc_etherdev ( sizeof ( struct libipw_device ) + sizeof_priv ) ;
2012-01-29 13:47:52 +00:00
if ( ! dev )
2005-05-12 22:48:20 -04:00
goto failed ;
2012-01-29 13:47:52 +00:00
2005-05-12 22:48:20 -04:00
ieee = netdev_priv ( dev ) ;
ieee - > dev = dev ;
2009-08-25 14:12:25 -04:00
if ( ! monitor ) {
ieee - > wdev . wiphy = wiphy_new ( & libipw_config_ops , 0 ) ;
if ( ! ieee - > wdev . wiphy ) {
LIBIPW_ERROR ( " Unable to allocate wiphy. \n " ) ;
goto failed_free_netdev ;
}
ieee - > dev - > ieee80211_ptr = & ieee - > wdev ;
ieee - > wdev . iftype = NL80211_IFTYPE_STATION ;
/* Fill-out wiphy structure bits we know... Not enough info
here to call set_wiphy_dev or set MAC address or channel info
- - have to do that in - > ndo_init . . . */
ieee - > wdev . wiphy - > privid = libipw_wiphy_privid ;
ieee - > wdev . wiphy - > max_scan_ssids = 1 ;
ieee - > wdev . wiphy - > max_scan_ie_len = 0 ;
ieee - > wdev . wiphy - > interface_modes = BIT ( NL80211_IFTYPE_STATION )
| BIT ( NL80211_IFTYPE_ADHOC ) ;
}
2009-08-20 14:48:03 -04:00
err = libipw_networks_allocate ( ieee ) ;
2005-05-12 22:48:20 -04:00
if ( err ) {
2009-08-20 14:48:03 -04:00
LIBIPW_ERROR ( " Unable to allocate beacon storage: %d \n " , err ) ;
2009-08-25 14:12:25 -04:00
goto failed_free_wiphy ;
2005-05-12 22:48:20 -04:00
}
2009-08-20 14:48:03 -04:00
libipw_networks_initialize ( ieee ) ;
2005-05-12 22:48:20 -04:00
/* Default fragmentation threshold is maximum payload size */
ieee - > fts = DEFAULT_FTS ;
2005-09-21 11:54:43 -05:00
ieee - > rts = DEFAULT_FTS ;
2005-05-12 22:48:20 -04:00
ieee - > scan_age = DEFAULT_MAX_SCAN_AGE ;
ieee - > open_wep = 1 ;
/* Default to enabling full open WEP with host based encrypt/decrypt */
ieee - > host_encrypt = 1 ;
ieee - > host_decrypt = 1 ;
2005-09-21 11:58:32 -05:00
ieee - > host_mc_decrypt = 1 ;
tree-wide: fix assorted typos all over the place
That is "success", "unknown", "through", "performance", "[re|un]mapping"
, "access", "default", "reasonable", "[con]currently", "temperature"
, "channel", "[un]used", "application", "example","hierarchy", "therefore"
, "[over|under]flow", "contiguous", "threshold", "enough" and others.
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2009-11-14 13:09:05 -02:00
/* Host fragmentation in Open mode. Default is enabled.
2005-09-21 11:54:53 -05:00
* Note : host fragmentation is always enabled if host encryption
* is enabled . For cards can do hardware encryption , they must do
* hardware fragmentation as well . So we don ' t need a variable
* like host_enc_frag . */
ieee - > host_open_frag = 1 ;
2005-09-07 00:48:31 -04:00
ieee - > ieee802_1x = 1 ; /* Default to supporting 802.1x */
2005-05-12 22:48:20 -04:00
spin_lock_init ( & ieee - > lock ) ;
2008-11-11 16:00:06 -05:00
lib80211_crypt_info_init ( & ieee - > crypt_info , dev - > name , & ieee - > lock ) ;
2008-10-29 11:35:05 -04:00
2005-09-07 00:48:31 -04:00
ieee - > wpa_enabled = 0 ;
ieee - > drop_unencrypted = 0 ;
ieee - > privacy_invoked = 0 ;
2005-05-12 22:48:20 -04:00
return dev ;
2009-08-25 14:12:25 -04:00
failed_free_wiphy :
if ( ! monitor )
wiphy_free ( ieee - > wdev . wiphy ) ;
2008-07-16 16:34:54 +02:00
failed_free_netdev :
free_netdev ( dev ) ;
failed :
2005-05-12 22:48:20 -04:00
return NULL ;
}
2010-03-12 00:01:22 -05:00
EXPORT_SYMBOL ( alloc_libipw ) ;
2005-05-12 22:48:20 -04:00
2010-03-12 00:01:22 -05:00
void free_libipw ( struct net_device * dev , int monitor )
2005-05-12 22:48:20 -04:00
{
2009-08-20 14:48:03 -04:00
struct libipw_device * ieee = netdev_priv ( dev ) ;
2005-05-12 22:48:20 -04:00
2008-11-11 16:00:06 -05:00
lib80211_crypt_info_free ( & ieee - > crypt_info ) ;
2005-05-12 22:48:20 -04:00
2009-08-20 14:48:03 -04:00
libipw_networks_free ( ieee ) ;
2009-08-25 14:12:25 -04:00
/* free cfg80211 resources */
if ( ! monitor )
wiphy_free ( ieee - > wdev . wiphy ) ;
2005-05-12 22:48:20 -04:00
free_netdev ( dev ) ;
}
2010-03-12 00:01:22 -05:00
EXPORT_SYMBOL ( free_libipw ) ;
2005-05-12 22:48:20 -04:00
2009-03-06 12:02:25 +01:00
# ifdef CONFIG_LIBIPW_DEBUG
2005-05-12 22:48:20 -04:00
static int debug = 0 ;
2009-08-20 14:48:03 -04:00
u32 libipw_debug_level = 0 ;
EXPORT_SYMBOL_GPL ( libipw_debug_level ) ;
static struct proc_dir_entry * libipw_proc = NULL ;
2005-05-12 22:48:20 -04:00
2009-11-25 10:14:12 +03:00
static int debug_level_proc_show ( struct seq_file * m , void * v )
2005-05-12 22:48:20 -04:00
{
2009-11-25 10:14:12 +03:00
seq_printf ( m , " 0x%08X \n " , libipw_debug_level ) ;
return 0 ;
2005-05-12 22:48:20 -04:00
}
2009-11-25 10:14:12 +03:00
static int debug_level_proc_open ( struct inode * inode , struct file * file )
{
return single_open ( file , debug_level_proc_show , NULL ) ;
}
static ssize_t debug_level_proc_write ( struct file * file ,
const char __user * buffer , size_t count , loff_t * pos )
2005-05-12 22:48:20 -04:00
{
2005-09-13 17:42:53 -05:00
char buf [ ] = " 0x00000000 \n " ;
2009-11-25 10:14:12 +03:00
size_t len = min ( sizeof ( buf ) - 1 , count ) ;
2005-05-12 22:48:20 -04:00
unsigned long val ;
2005-09-13 17:42:53 -05:00
if ( copy_from_user ( buf , buffer , len ) )
2005-05-12 22:48:20 -04:00
return count ;
2005-09-13 17:42:53 -05:00
buf [ len ] = 0 ;
if ( sscanf ( buf , " %li " , & val ) ! = 1 )
2005-05-12 22:48:20 -04:00
printk ( KERN_INFO DRV_NAME
" : %s is not in hex or decimal form. \n " , buf ) ;
else
2009-08-20 14:48:03 -04:00
libipw_debug_level = val ;
2005-05-12 22:48:20 -04:00
2005-09-13 17:42:53 -05:00
return strnlen ( buf , len ) ;
2005-05-12 22:48:20 -04:00
}
2009-11-25 10:14:12 +03:00
static const struct file_operations debug_level_proc_fops = {
. owner = THIS_MODULE ,
. open = debug_level_proc_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
. write = debug_level_proc_write ,
} ;
2009-03-06 12:02:25 +01:00
# endif /* CONFIG_LIBIPW_DEBUG */
2005-05-12 22:48:20 -04:00
2009-08-20 14:48:03 -04:00
static int __init libipw_init ( void )
2005-05-12 22:48:20 -04:00
{
2009-03-06 12:02:25 +01:00
# ifdef CONFIG_LIBIPW_DEBUG
2005-05-12 22:48:20 -04:00
struct proc_dir_entry * e ;
2009-08-20 14:48:03 -04:00
libipw_debug_level = debug ;
2010-11-05 18:57:04 -07:00
libipw_proc = proc_mkdir ( DRV_PROCNAME , init_net . proc_net ) ;
2009-08-20 14:48:03 -04:00
if ( libipw_proc = = NULL ) {
2010-11-05 18:57:04 -07:00
LIBIPW_ERROR ( " Unable to create " DRV_PROCNAME
2005-05-12 22:48:20 -04:00
" proc directory \n " ) ;
return - EIO ;
}
2009-11-25 10:14:12 +03:00
e = proc_create ( " debug_level " , S_IRUGO | S_IWUSR , libipw_proc ,
& debug_level_proc_fops ) ;
2005-05-12 22:48:20 -04:00
if ( ! e ) {
2010-11-05 18:57:04 -07:00
remove_proc_entry ( DRV_PROCNAME , init_net . proc_net ) ;
2009-08-20 14:48:03 -04:00
libipw_proc = NULL ;
2005-05-12 22:48:20 -04:00
return - EIO ;
}
2009-03-06 12:02:25 +01:00
# endif /* CONFIG_LIBIPW_DEBUG */
2005-09-21 11:58:46 -05:00
printk ( KERN_INFO DRV_NAME " : " DRV_DESCRIPTION " , " DRV_VERSION " \n " ) ;
printk ( KERN_INFO DRV_NAME " : " DRV_COPYRIGHT " \n " ) ;
2005-05-12 22:48:20 -04:00
return 0 ;
}
2009-08-20 14:48:03 -04:00
static void __exit libipw_exit ( void )
2005-05-12 22:48:20 -04:00
{
2009-03-06 12:02:25 +01:00
# ifdef CONFIG_LIBIPW_DEBUG
2009-08-20 14:48:03 -04:00
if ( libipw_proc ) {
remove_proc_entry ( " debug_level " , libipw_proc ) ;
2010-11-05 18:57:04 -07:00
remove_proc_entry ( DRV_PROCNAME , init_net . proc_net ) ;
2009-08-20 14:48:03 -04:00
libipw_proc = NULL ;
2005-05-12 22:48:20 -04:00
}
2009-03-06 12:02:25 +01:00
# endif /* CONFIG_LIBIPW_DEBUG */
2005-05-12 22:48:20 -04:00
}
2009-03-06 12:02:25 +01:00
# ifdef CONFIG_LIBIPW_DEBUG
2005-05-12 22:48:20 -04:00
# include <linux/moduleparam.h>
module_param ( debug , int , 0444 ) ;
MODULE_PARM_DESC ( debug , " debug output mask " ) ;
2009-03-06 12:02:25 +01:00
# endif /* CONFIG_LIBIPW_DEBUG */
2005-05-12 22:48:20 -04:00
2009-08-20 14:48:03 -04:00
module_exit ( libipw_exit ) ;
module_init ( libipw_init ) ;