Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
deeee3bf
Commit
deeee3bf
authored
Oct 19, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge pobox.com:/spare/repo/netdev-2.6/wireless-ext
into pobox.com:/spare/repo/net-drivers-2.6
parents
a4946826
4958c29f
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
305 additions
and
128 deletions
+305
-128
drivers/net/wireless/airo.c
drivers/net/wireless/airo.c
+30
-15
drivers/net/wireless/wavelan.c
drivers/net/wireless/wavelan.c
+12
-7
drivers/net/wireless/wavelan.p.h
drivers/net/wireless/wavelan.p.h
+3
-0
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wavelan_cs.c
+14
-9
drivers/net/wireless/wavelan_cs.p.h
drivers/net/wireless/wavelan_cs.p.h
+3
-0
include/linux/netdevice.h
include/linux/netdevice.h
+3
-1
include/linux/wireless.h
include/linux/wireless.h
+52
-12
include/net/iw_handler.h
include/net/iw_handler.h
+42
-18
net/core/dev.c
net/core/dev.c
+1
-1
net/core/wireless.c
net/core/wireless.c
+145
-65
No files found.
drivers/net/wireless/airo.c
View file @
deeee3bf
...
...
@@ -1189,6 +1189,7 @@ struct airo_info {
struct
iw_statistics
wstats
;
// wireless stats
unsigned
long
scan_timestamp
;
/* Time started to scan */
struct
iw_spy_data
spy_data
;
struct
iw_public_data
wireless_data
;
#endif
/* WIRELESS_EXT */
#ifdef MICSUPPORT
/* MIC stuff */
...
...
@@ -2640,8 +2641,7 @@ static void wifi_setup(struct net_device *dev)
dev
->
set_mac_address
=
&
airo_set_mac_address
;
dev
->
do_ioctl
=
&
airo_ioctl
;
#ifdef WIRELESS_EXT
dev
->
get_wireless_stats
=
airo_get_wireless_stats
;
dev
->
wireless_handlers
=
(
struct
iw_handler_def
*
)
&
airo_handler_def
;
dev
->
wireless_handlers
=
&
airo_handler_def
;
#endif
/* WIRELESS_EXT */
dev
->
change_mtu
=
&
airo_change_mtu
;
dev
->
open
=
&
airo_open
;
...
...
@@ -2668,6 +2668,9 @@ static struct net_device *init_wifidev(struct airo_info *ai,
dev
->
priv
=
ethdev
->
priv
;
dev
->
irq
=
ethdev
->
irq
;
dev
->
base_addr
=
ethdev
->
base_addr
;
#ifdef WIRELESS_EXT
dev
->
wireless_data
=
ethdev
->
wireless_data
;
#endif
/* WIRELESS_EXT */
memcpy
(
dev
->
dev_addr
,
ethdev
->
dev_addr
,
dev
->
addr_len
);
err
=
register_netdev
(
dev
);
if
(
err
<
0
)
{
...
...
@@ -2747,8 +2750,9 @@ struct net_device *_init_airo_card( unsigned short irq, int port,
dev
->
set_mac_address
=
&
airo_set_mac_address
;
dev
->
do_ioctl
=
&
airo_ioctl
;
#ifdef WIRELESS_EXT
dev
->
get_wireless_stats
=
airo_get_wireless_stats
;
dev
->
wireless_handlers
=
(
struct
iw_handler_def
*
)
&
airo_handler_def
;
dev
->
wireless_handlers
=
&
airo_handler_def
;
ai
->
wireless_data
.
spy_data
=
&
ai
->
spy_data
;
dev
->
wireless_data
=
&
ai
->
wireless_data
;
#endif
/* WIRELESS_EXT */
dev
->
change_mtu
=
&
airo_change_mtu
;
dev
->
open
=
&
airo_open
;
...
...
@@ -3231,7 +3235,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
goto
exitrx
;
}
}
#ifdef
IW_WIRELESS_SPY
/* defined in iw_handler.h */
#ifdef
WIRELESS_SPY
if
(
apriv
->
spy_data
.
spy_number
>
0
)
{
char
*
sa
;
struct
iw_quality
wstats
;
...
...
@@ -3251,7 +3255,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
/* Update spy records */
wireless_spy_update
(
dev
,
sa
,
&
wstats
);
}
#endif
/*
IW_
WIRELESS_SPY */
#endif
/* WIRELESS_SPY */
OUT4500
(
apriv
,
EVACK
,
EV_RX
);
if
(
test_bit
(
FLAG_802_11
,
&
apriv
->
flags
))
{
...
...
@@ -3476,7 +3480,7 @@ static void mpi_receive_802_3(struct airo_info *ai)
#else
memcpy
(
buffer
,
ai
->
rxfids
[
0
].
virtual_host_addr
,
len
);
#endif
#ifdef
IW_WIRELESS_SPY
/* defined in iw_handler.h */
#ifdef
WIRELESS_SPY
if
(
ai
->
spy_data
.
spy_number
>
0
)
{
char
*
sa
;
struct
iw_quality
wstats
;
...
...
@@ -3488,7 +3492,7 @@ static void mpi_receive_802_3(struct airo_info *ai)
/* Update spy records */
wireless_spy_update
(
ai
->
dev
,
sa
,
&
wstats
);
}
#endif
/*
IW_
WIRELESS_SPY */
#endif
/* WIRELESS_SPY */
skb
->
dev
=
ai
->
dev
;
skb
->
ip_summed
=
CHECKSUM_NONE
;
...
...
@@ -6520,6 +6524,13 @@ static int airo_get_range(struct net_device *dev,
range
->
avg_qual
.
level
=
176
;
/* -80 dBm */
range
->
avg_qual
.
noise
=
0
;
/* Event capability (kernel + driver) */
range
->
event_capa
[
0
]
=
(
IW_EVENT_CAPA_K_0
|
IW_EVENT_CAPA_MASK
(
SIOCGIWTHRSPY
)
|
IW_EVENT_CAPA_MASK
(
SIOCGIWAP
)
|
IW_EVENT_CAPA_MASK
(
SIOCGIWSCAN
));
range
->
event_capa
[
1
]
=
IW_EVENT_CAPA_K_1
;
range
->
event_capa
[
4
]
=
IW_EVENT_CAPA_MASK
(
IWEVTXDROP
);
return
0
;
}
...
...
@@ -6887,9 +6898,15 @@ static int airo_get_scan(struct net_device *dev,
while
((
!
rc
)
&&
(
BSSList
.
index
!=
0xffff
))
{
/* Translate to WE format this entry */
current_ev
=
airo_translate_scan
(
dev
,
current_ev
,
extra
+
IW_SCAN_MAX_DATA
,
extra
+
dwrq
->
length
,
&
BSSList
);
/* Check if there is space for one more entry */
if
((
extra
+
dwrq
->
length
-
current_ev
)
<=
IW_EV_ADDR_LEN
)
{
/* Ask user space to try again with a bigger buffer */
return
-
E2BIG
;
}
/* Read next entry */
rc
=
PC4500_readrid
(
ai
,
RID_BSSLISTNEXT
,
&
BSSList
,
sizeof
(
BSSList
),
1
);
...
...
@@ -7025,12 +7042,10 @@ static const struct iw_handler_def airo_handler_def =
.
num_standard
=
sizeof
(
airo_handler
)
/
sizeof
(
iw_handler
),
.
num_private
=
sizeof
(
airo_private_handler
)
/
sizeof
(
iw_handler
),
.
num_private_args
=
sizeof
(
airo_private_args
)
/
sizeof
(
struct
iw_priv_args
),
.
standard
=
(
iw_handler
*
)
airo_handler
,
.
private
=
(
iw_handler
*
)
airo_private_handler
,
.
private_args
=
(
struct
iw_priv_args
*
)
airo_private_args
,
.
spy_offset
=
((
void
*
)
(
&
((
struct
airo_info
*
)
NULL
)
->
spy_data
)
-
(
void
*
)
NULL
),
.
standard
=
airo_handler
,
.
private
=
airo_private_handler
,
.
private_args
=
airo_private_args
,
.
get_wireless_stats
=
airo_get_wireless_stats
,
};
#endif
/* WIRELESS_EXT */
...
...
drivers/net/wireless/wavelan.c
View file @
deeee3bf
...
...
@@ -2172,6 +2172,11 @@ static int wavelan_get_range(struct net_device *dev,
range
->
num_bitrates
=
1
;
range
->
bitrate
[
0
]
=
2000000
;
/* 2 Mb/s */
/* Event capability (kernel + driver) */
range
->
event_capa
[
0
]
=
(
IW_EVENT_CAPA_MASK
(
0x8B02
)
|
IW_EVENT_CAPA_MASK
(
0x8B04
));
range
->
event_capa
[
1
]
=
IW_EVENT_CAPA_K_1
;
/* Disable interrupts and save flags. */
spin_lock_irqsave
(
&
lp
->
spinlock
,
flags
);
...
...
@@ -2403,11 +2408,10 @@ static const struct iw_handler_def wavelan_handler_def =
.
num_standard
=
sizeof
(
wavelan_handler
)
/
sizeof
(
iw_handler
),
.
num_private
=
sizeof
(
wavelan_private_handler
)
/
sizeof
(
iw_handler
),
.
num_private_args
=
sizeof
(
wavelan_private_args
)
/
sizeof
(
struct
iw_priv_args
),
.
standard
=
(
iw_handler
*
)
wavelan_handler
,
.
private
=
(
iw_handler
*
)
wavelan_private_handler
,
.
private_args
=
(
struct
iw_priv_args
*
)
wavelan_private_args
,
.
spy_offset
=
((
void
*
)
(
&
((
net_local
*
)
NULL
)
->
spy_data
)
-
(
void
*
)
NULL
),
.
standard
=
wavelan_handler
,
.
private
=
wavelan_private_handler
,
.
private_args
=
wavelan_private_args
,
.
get_wireless_stats
=
wavelan_get_wireless_stats
,
};
/*------------------------------------------------------------------*/
...
...
@@ -4191,8 +4195,9 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
#endif
/* SET_MAC_ADDRESS */
#ifdef WIRELESS_EXT
/* if wireless extension exists in the kernel */
dev
->
get_wireless_stats
=
wavelan_get_wireless_stats
;
dev
->
wireless_handlers
=
(
struct
iw_handler_def
*
)
&
wavelan_handler_def
;
dev
->
wireless_handlers
=
&
wavelan_handler_def
;
lp
->
wireless_data
.
spy_data
=
&
lp
->
spy_data
;
dev
->
wireless_data
=
&
lp
->
wireless_data
;
#endif
dev
->
mtu
=
WAVELAN_MTU
;
...
...
drivers/net/wireless/wavelan.p.h
View file @
deeee3bf
...
...
@@ -510,6 +510,7 @@ struct net_local
iw_stats
wstats
;
/* Wireless-specific statistics */
struct
iw_spy_data
spy_data
;
struct
iw_public_data
wireless_data
;
#endif
#ifdef HISTOGRAM
...
...
@@ -614,6 +615,8 @@ static inline void
/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
static
en_stats
*
wavelan_get_stats
(
struct
net_device
*
);
/* Give stats /proc/net/dev */
static
iw_stats
*
wavelan_get_wireless_stats
(
struct
net_device
*
);
static
void
wavelan_set_multicast_list
(
struct
net_device
*
);
/* ----------------------- PACKET RECEPTION ----------------------- */
...
...
drivers/net/wireless/wavelan_cs.c
View file @
deeee3bf
...
...
@@ -1550,7 +1550,6 @@ wavelan_set_mac_address(struct net_device * dev,
/*
* Frequency setting (for hardware able of it)
* It's a bit complicated and you don't really want to look into it...
* (called in wavelan_ioctl)
*/
static
inline
int
wv_set_frequency
(
u_long
base
,
/* i/o port of the card */
...
...
@@ -2438,6 +2437,12 @@ static int wavelan_get_range(struct net_device *dev,
range
->
num_bitrates
=
1
;
range
->
bitrate
[
0
]
=
2000000
;
/* 2 Mb/s */
/* Event capability (kernel + driver) */
range
->
event_capa
[
0
]
=
(
IW_EVENT_CAPA_MASK
(
0x8B02
)
|
IW_EVENT_CAPA_MASK
(
0x8B04
)
|
IW_EVENT_CAPA_MASK
(
0x8B06
));
range
->
event_capa
[
1
]
=
IW_EVENT_CAPA_K_1
;
/* Disable interrupts and save flags. */
spin_lock_irqsave
(
&
lp
->
spinlock
,
flags
);
...
...
@@ -2737,11 +2742,10 @@ static const struct iw_handler_def wavelan_handler_def =
.
num_standard
=
sizeof
(
wavelan_handler
)
/
sizeof
(
iw_handler
),
.
num_private
=
sizeof
(
wavelan_private_handler
)
/
sizeof
(
iw_handler
),
.
num_private_args
=
sizeof
(
wavelan_private_args
)
/
sizeof
(
struct
iw_priv_args
),
.
standard
=
(
iw_handler
*
)
wavelan_handler
,
.
private
=
(
iw_handler
*
)
wavelan_private_handler
,
.
private_args
=
(
struct
iw_priv_args
*
)
wavelan_private_args
,
.
spy_offset
=
((
void
*
)
(
&
((
net_local
*
)
NULL
)
->
spy_data
)
-
(
void
*
)
NULL
),
.
standard
=
wavelan_handler
,
.
private
=
wavelan_private_handler
,
.
private_args
=
wavelan_private_args
,
.
get_wireless_stats
=
wavelan_get_wireless_stats
,
};
/*------------------------------------------------------------------*/
...
...
@@ -4720,9 +4724,10 @@ wavelan_attach(void)
dev
->
watchdog_timeo
=
WATCHDOG_JIFFIES
;
#ifdef WIRELESS_EXT
/* If wireless extension exist in the kernel */
dev
->
wireless_handlers
=
(
struct
iw_handler_def
*
)
&
wavelan_handler_def
;
dev
->
do_ioctl
=
wavelan_ioctl
;
/* old wireless extensions */
dev
->
get_wireless_stats
=
wavelan_get_wireless_stats
;
dev
->
wireless_handlers
=
&
wavelan_handler_def
;
dev
->
do_ioctl
=
wavelan_ioctl
;
/* ethtool */
lp
->
wireless_data
.
spy_data
=
&
lp
->
spy_data
;
dev
->
wireless_data
=
&
lp
->
wireless_data
;
#endif
/* Other specific data */
...
...
drivers/net/wireless/wavelan_cs.p.h
View file @
deeee3bf
...
...
@@ -629,6 +629,7 @@ struct net_local
iw_stats
wstats
;
/* Wireless specific stats */
struct
iw_spy_data
spy_data
;
struct
iw_public_data
wireless_data
;
#endif
#ifdef HISTOGRAM
...
...
@@ -725,6 +726,8 @@ static inline void
/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
static
en_stats
*
wavelan_get_stats
(
struct
net_device
*
);
/* Give stats /proc/net/dev */
static
iw_stats
*
wavelan_get_wireless_stats
(
struct
net_device
*
);
/* ----------------------- PACKET RECEPTION ----------------------- */
static
inline
int
wv_start_of_frame
(
struct
net_device
*
,
/* Seek beggining of current frame */
...
...
include/linux/netdevice.h
View file @
deeee3bf
...
...
@@ -309,7 +309,9 @@ struct net_device
/* List of functions to handle Wireless Extensions (instead of ioctl).
* See <net/iw_handler.h> for details. Jean II */
struct
iw_handler_def
*
wireless_handlers
;
const
struct
iw_handler_def
*
wireless_handlers
;
/* Instance data managed by the core of Wireless Extensions. */
struct
iw_public_data
*
wireless_data
;
struct
ethtool_ops
*
ethtool_ops
;
...
...
include/linux/wireless.h
View file @
deeee3bf
/*
* This file define a set of standard wireless extensions
*
* Version : 1
6 2.4.03
* Version : 1
7 21.6.04
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-200
2
Jean Tourrilhes, All Rights Reserved.
* Copyright (c) 1997-200
4
Jean Tourrilhes, All Rights Reserved.
*/
#ifndef _LINUX_WIRELESS_H
...
...
@@ -47,12 +47,12 @@
* # include/net/iw_handler.h
*
* Note as well that /proc/net/wireless implementation has now moved in :
* #
include/linux
/wireless.c
* #
net/core
/wireless.c
*
* Wireless Events (2002 -> onward) :
* --------------------------------
* Events are defined at the end of this file, and implemented in :
* #
include/linux
/wireless.c
* #
net/core
/wireless.c
*
* Other comments :
* --------------
...
...
@@ -82,7 +82,7 @@
* (there is some stuff that will be added in the future...)
* I just plan to increment with each new version.
*/
#define WIRELESS_EXT 1
6
#define WIRELESS_EXT 1
7
/*
* Changes :
...
...
@@ -175,6 +175,13 @@
* - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
* - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
* - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
*
* V16 to V17
* ----------
* - Add flags to frequency -> auto/fixed
* - Document (struct iw_quality *)->updated, add new flags (INVALID)
* - Wireless Event capability in struct iw_range
* - Add support for relative TxPower (yick !)
*/
/**************************** CONSTANTS ****************************/
...
...
@@ -251,7 +258,7 @@
/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
/* These
16 ioctl are wireless device private
.
/* These
32 ioctl are wireless device private, for 16 commands
.
* Each driver is free to use them for whatever purpose it chooses,
* however the driver *must* export the description of those ioctls
* with SIOCGIWPRIV and *must* use arguments as defined below.
...
...
@@ -266,8 +273,8 @@
* We now have 32 commands, so a bit more space ;-).
* Also, all 'odd' commands are only usable by root and don't return the
* content of ifr/iwr to user (but you are not obliged to use the set/get
* convention, just use every other two command).
* And I repeat : you are not
obliged to use them with iwspy
, but you
* convention, just use every other two command).
More details in iwpriv.c.
* And I repeat : you are not
forced to use them with iwpriv
, but you
* must be compliant with it.
*/
...
...
@@ -352,6 +359,18 @@
#define IW_MODE_SECOND 5
/* Secondary master/repeater (backup) */
#define IW_MODE_MONITOR 6
/* Passive monitor (listen only) */
/* Statistics flags (bitmask in updated) */
#define IW_QUAL_QUAL_UPDATED 0x1
/* Value was updated since last read */
#define IW_QUAL_LEVEL_UPDATED 0x2
#define IW_QUAL_NOISE_UPDATED 0x4
#define IW_QUAL_QUAL_INVALID 0x10
/* Driver doesn't provide value */
#define IW_QUAL_LEVEL_INVALID 0x20
#define IW_QUAL_NOISE_INVALID 0x40
/* Frequency flags */
#define IW_FREQ_AUTO 0x00
/* Let the driver decides */
#define IW_FREQ_FIXED 0x01
/* Force a specific value */
/* Maximum number of size of encoding token available
* they are listed in the range structure */
#define IW_MAX_ENCODING_SIZES 8
...
...
@@ -390,6 +409,7 @@
#define IW_TXPOW_TYPE 0x00FF
/* Type of value */
#define IW_TXPOW_DBM 0x0000
/* Value is in dBm */
#define IW_TXPOW_MWATT 0x0001
/* Value is in mW */
#define IW_TXPOW_RELATIVE 0x0002
/* Value is in arbitrary units */
#define IW_TXPOW_RANGE 0x1000
/* Range of value between min/max */
/* Retry limits and lifetime flags available */
...
...
@@ -418,6 +438,25 @@
/* Max number of char in custom event - use multiple of them if needed */
#define IW_CUSTOM_MAX 256
/* In bytes */
/* Event capability macros - in (struct iw_range *)->event_capa
* Because we have more than 32 possible events, we use an array of
* 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \
(cmd - SIOCIWFIRSTPRIV + 0x60) : \
(cmd - SIOCSIWCOMMIT))
#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5)
#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F))
/* Event capability constants - event autogenerated by the kernel
* This list is valid for most 802.11 devices, customise as needed... */
#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \
IW_EVENT_CAPA_MASK(0x8B06) | \
IW_EVENT_CAPA_MASK(0x8B1A))
#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A))
/* "Easy" macro to set events in iw_range (less efficient) */
#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd))
#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; }
/****************************** TYPES ******************************/
/* --------------------------- SUBTYPES --------------------------- */
...
...
@@ -456,7 +495,7 @@ struct iw_freq
__s32
m
;
/* Mantissa */
__s16
e
;
/* Exponent */
__u8
i
;
/* List index (when in range struct) */
__u8
pad
;
/* Unused - just for alignement
*/
__u8
flags
;
/* Flags (fixed/auto)
*/
};
/*
...
...
@@ -610,11 +649,12 @@ struct iw_range
/* Old Frequency (backward compat - moved lower ) */
__u16
old_num_channels
;
__u8
old_num_frequency
;
/* Filler to keep "version" at the same offset */
__s32
old_freq
[
6
];
/* Wireless event capability bitmasks */
__u32
event_capa
[
6
];
/* signal level threshold range */
__s32
sensitivity
;
__s32
sensitivity
;
/* Quality of link & SNR stuff */
/* Quality range (link, level, noise)
...
...
include/net/iw_handler.h
View file @
deeee3bf
/*
* This file define the new driver API for Wireless Extensions
*
* Version :
5 4.12.02
* Version :
6 21.6.04
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 2001-200
2
Jean Tourrilhes, All Rights Reserved.
* Copyright (c) 2001-200
4
Jean Tourrilhes, All Rights Reserved.
*/
#ifndef _IW_HANDLER_H
...
...
@@ -206,7 +206,7 @@
* will be needed...
* I just plan to increment with each new version.
*/
#define IW_HANDLER_VERSION
5
#define IW_HANDLER_VERSION
6
/*
* Changes :
...
...
@@ -224,11 +224,18 @@
* V4 to V5
* --------
* - Add new spy support : struct iw_spy_data & prototypes
*
* V5 to V6
* --------
* - Change the way we get to spy_data method for added safety
* - Remove spy #ifdef, they are always on -> cleaner code
* - Add IW_DESCR_FLAG_NOMAX flag for very large requests
* - Start migrating get_wireless_stats to struct iw_handler_def
*/
/**************************** CONSTANTS ****************************/
/* En
able enhanced spy support. Disable to reduce footprint
*/
/* En
hanced spy support available
*/
#define IW_WIRELESS_SPY
#define IW_WIRELESS_THRSPY
...
...
@@ -258,6 +265,7 @@
#define IW_DESCR_FLAG_EVENT 0x0002
/* Generate an event on SET */
#define IW_DESCR_FLAG_RESTRICT 0x0004
/* GET : request is ROOT only */
/* SET : Omit payload from generated iwevent */
#define IW_DESCR_FLAG_NOMAX 0x0008
/* GET : no limit on request size */
/* Driver level flags */
#define IW_DESCR_FLAG_WAIT 0x0100
/* Wait for driver event */
...
...
@@ -303,31 +311,33 @@ struct iw_handler_def
{
/* Number of handlers defined (more precisely, index of the
* last defined handler + 1) */
__u16
num_standard
;
__u16
num_private
;
const
__u16
num_standard
;
const
__u16
num_private
;
/* Number of private arg description */
__u16
num_private_args
;
const
__u16
num_private_args
;
/* Array of handlers for standard ioctls
* We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
*/
iw_handler
*
standard
;
const
iw_handler
*
standard
;
/* Array of handlers for private ioctls
* Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
*/
iw_handler
*
private
;
const
iw_handler
*
private
;
/* Arguments of private handler. This one is just a list, so you
* can put it in any order you want and should not leave holes...
* We will automatically export that to user space... */
struct
iw_priv_args
*
private_args
;
const
struct
iw_priv_args
*
private_args
;
/*
Driver enhanced spy support
*/
long
spy_offset
;
/* Spy data offset
*/
/*
This field will be *removed* in the next version of WE
*/
const
long
spy_offset
;
/* DO NOT USE
*/
/* In the long term, get_wireless_stats will move from
* 'struct net_device' to here, to minimise bloat. */
/* New location of get_wireless_stats, to de-bloat struct net_device.
* The old pointer in struct net_device will be gradually phased
* out, and drivers are encouraged to use this one... */
struct
iw_statistics
*
(
*
get_wireless_stats
)(
struct
net_device
*
dev
);
};
/* ---------------------- IOCTL DESCRIPTION ---------------------- */
...
...
@@ -374,18 +384,29 @@ struct iw_ioctl_description
*/
struct
iw_spy_data
{
#ifdef IW_WIRELESS_SPY
/* --- Standard spy support --- */
int
spy_number
;
u_char
spy_address
[
IW_MAX_SPY
][
ETH_ALEN
];
struct
iw_quality
spy_stat
[
IW_MAX_SPY
];
#ifdef IW_WIRELESS_THRSPY
/* --- Enhanced spy support (event) */
struct
iw_quality
spy_thr_low
;
/* Low threshold */
struct
iw_quality
spy_thr_high
;
/* High threshold */
u_char
spy_thr_under
[
IW_MAX_SPY
];
#endif
/* IW_WIRELESS_THRSPY */
#endif
/* IW_WIRELESS_SPY */
};
/* --------------------- DEVICE WIRELESS DATA --------------------- */
/*
* This is all the wireless data specific to a device instance that
* is managed by the core of Wireless Extensions.
* We only keep pointer to those structures, so that a driver is free
* to share them between instances.
* This structure should be initialised before registering the device.
* Access to this data follow the same rules as any other struct net_device
* data (i.e. valid as long as struct net_device exist, same locking rules).
*/
struct
iw_public_data
{
/* Driver enhanced spy support */
struct
iw_spy_data
*
spy_data
;
};
/**************************** PROTOTYPES ****************************/
...
...
@@ -394,6 +415,9 @@ struct iw_spy_data
* Those may be called only within the kernel.
*/
/* Data needed by fs/compat_ioctl.c for 32->64 bit conversion */
extern
const
char
iw_priv_type_size
[];
/* First : function strictly used inside the kernel */
/* Handle /proc/net/wireless, called in net/code/dev.c */
...
...
net/core/dev.c
View file @
deeee3bf
...
...
@@ -2745,7 +2745,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
/* Follow me in net/core/wireless.c */
ret
=
wireless_process_ioctl
(
&
ifr
,
cmd
);
rtnl_unlock
();
if
(
!
ret
&&
IW_IS_GET
(
cmd
)
&&
if
(
IW_IS_GET
(
cmd
)
&&
copy_to_user
(
arg
,
&
ifr
,
sizeof
(
struct
ifreq
)))
ret
=
-
EFAULT
;
...
...
net/core/wireless.c
View file @
deeee3bf
...
...
@@ -2,7 +2,7 @@
* This file implement the Wireless Extensions APIs.
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
* Copyright (c) 1997-200
3
Jean Tourrilhes, All Rights Reserved.
* Copyright (c) 1997-200
4
Jean Tourrilhes, All Rights Reserved.
*
* (As all part of the Linux kernel, this file is GPL)
*/
...
...
@@ -48,6 +48,15 @@
* o Add common spy support : iw_handler_set_spy(), wireless_spy_update()
* o Add enhanced spy support : iw_handler_set_thrspy() and event.
* o Add WIRELESS_EXT version display in /proc/net/wireless
*
* v6 - 18.06.04 - Jean II
* o Change get_spydata() method for added safety
* o Remove spy #ifdef, they are always on -> cleaner code
* o Allow any size GET request is user specifies length > max
* o Start migrating get_wireless_stats to struct iw_handler_def
* o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus
* Based on patch from Pavel Roskin <proski@gnu.org> :
* o Fix kernel data leak to user space in private handler handling
*/
/***************************** INCLUDES *****************************/
...
...
@@ -69,10 +78,6 @@
/**************************** CONSTANTS ****************************/
/* Enough lenience, let's make sure things are proper... */
#define WE_STRICT_WRITE
/* Check write buffer size */
/* I'll probably drop both the define and kernel message in the next version */
/* Debugging stuff */
#undef WE_IOCTL_DEBUG
/* Debug IOCTL API */
#undef WE_EVENT_DEBUG
/* Debug Event dispatcher */
...
...
@@ -186,6 +191,7 @@ static const struct iw_ioctl_description standard_ioctl[] = {
.
token_size
=
sizeof
(
struct
sockaddr
)
+
sizeof
(
struct
iw_quality
),
.
max_tokens
=
IW_MAX_AP
,
.
flags
=
IW_DESCR_FLAG_NOMAX
,
},
[
SIOCSIWSCAN
-
SIOCIWFIRST
]
=
{
.
header_type
=
IW_HEADER_TYPE_PARAM
,
...
...
@@ -194,6 +200,7 @@ static const struct iw_ioctl_description standard_ioctl[] = {
.
header_type
=
IW_HEADER_TYPE_POINT
,
.
token_size
=
1
,
.
max_tokens
=
IW_SCAN_MAX_DATA
,
.
flags
=
IW_DESCR_FLAG_NOMAX
,
},
[
SIOCSIWESSID
-
SIOCIWFIRST
]
=
{
.
header_type
=
IW_HEADER_TYPE_POINT
,
...
...
@@ -296,7 +303,7 @@ static const int standard_event_num = (sizeof(standard_event) /
sizeof
(
struct
iw_ioctl_description
));
/* Size (in bytes) of the various private data types */
static
const
char
priv_type_size
[]
=
{
const
char
iw_
priv_type_size
[]
=
{
0
,
/* IW_PRIV_TYPE_NONE */
1
,
/* IW_PRIV_TYPE_BYTE */
1
,
/* IW_PRIV_TYPE_CHAR */
...
...
@@ -363,12 +370,15 @@ static inline iw_handler get_handler(struct net_device *dev,
*/
static
inline
struct
iw_statistics
*
get_wireless_stats
(
struct
net_device
*
dev
)
{
/* New location */
if
((
dev
->
wireless_handlers
!=
NULL
)
&&
(
dev
->
wireless_handlers
->
get_wireless_stats
!=
NULL
))
return
dev
->
wireless_handlers
->
get_wireless_stats
(
dev
);
/* Old location, will be phased out in next WE */
return
(
dev
->
get_wireless_stats
?
dev
->
get_wireless_stats
(
dev
)
:
(
struct
iw_statistics
*
)
NULL
);
/* In the future, get_wireless_stats may move from 'struct net_device'
* to 'struct iw_handler_def', to de-bloat struct net_device.
* Definitely worse a thought... */
}
/* ---------------------------------------------------------------- */
...
...
@@ -403,14 +413,32 @@ static inline int call_commit_handler(struct net_device * dev)
/* ---------------------------------------------------------------- */
/*
*
Number
of private arguments
*
Calculate size
of private arguments
*/
static
inline
int
get_priv_size
(
__u16
args
)
{
int
num
=
args
&
IW_PRIV_SIZE_MASK
;
int
type
=
(
args
&
IW_PRIV_TYPE_MASK
)
>>
12
;
return
num
*
priv_type_size
[
type
];
return
num
*
iw_priv_type_size
[
type
];
}
/* ---------------------------------------------------------------- */
/*
* Re-calculate the size of private arguments
*/
static
inline
int
adjust_priv_size
(
__u16
args
,
union
iwreq_data
*
wrqu
)
{
int
num
=
wrqu
->
data
.
length
;
int
max
=
args
&
IW_PRIV_SIZE_MASK
;
int
type
=
(
args
&
IW_PRIV_TYPE_MASK
)
>>
12
;
/* Make sure the driver doesn't goof up */
if
(
max
<
num
)
num
=
max
;
return
num
*
iw_priv_type_size
[
type
];
}
...
...
@@ -440,11 +468,14 @@ static __inline__ void wireless_seq_printf_stats(struct seq_file *seq,
seq_printf
(
seq
,
"%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d "
"%6d %6d %6d
\n
"
,
dev
->
name
,
stats
->
status
,
stats
->
qual
.
qual
,
stats
->
qual
.
updated
&
1
?
'.'
:
' '
,
stats
->
qual
.
updated
&
IW_QUAL_QUAL_UPDATED
?
'.'
:
' '
,
((
__u8
)
stats
->
qual
.
level
),
stats
->
qual
.
updated
&
2
?
'.'
:
' '
,
stats
->
qual
.
updated
&
IW_QUAL_LEVEL_UPDATED
?
'.'
:
' '
,
((
__u8
)
stats
->
qual
.
noise
),
stats
->
qual
.
updated
&
4
?
'.'
:
' '
,
stats
->
qual
.
updated
&
IW_QUAL_NOISE_UPDATED
?
'.'
:
' '
,
stats
->
discard
.
nwid
,
stats
->
discard
.
code
,
stats
->
discard
.
fragment
,
stats
->
discard
.
retries
,
stats
->
discard
.
misc
,
stats
->
miss
.
beacon
);
...
...
@@ -555,13 +586,15 @@ static inline int ioctl_export_private(struct net_device * dev,
/* Check NULL pointer */
if
(
iwr
->
u
.
data
.
pointer
==
NULL
)
return
-
EFAULT
;
#ifdef WE_STRICT_WRITE
/* Check if there is enough buffer up there */
if
(
iwr
->
u
.
data
.
length
<
dev
->
wireless_handlers
->
num_private_args
)
{
printk
(
KERN_ERR
"%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)
\n
"
,
dev
->
name
,
iwr
->
u
.
data
.
length
,
dev
->
wireless_handlers
->
num_private_args
);
/* User space can't know in advance how large the buffer
* needs to be. Give it a hint, so that we can support
* any size buffer we want somewhat efficiently... */
iwr
->
u
.
data
.
length
=
dev
->
wireless_handlers
->
num_private_args
;
return
-
E2BIG
;
}
#endif
/* WE_STRICT_WRITE */
/* Set the number of available ioctls. */
iwr
->
u
.
data
.
length
=
dev
->
wireless_handlers
->
num_private_args
;
...
...
@@ -590,7 +623,6 @@ static inline int ioctl_standard_call(struct net_device * dev,
const
struct
iw_ioctl_description
*
descr
;
struct
iw_request_info
info
;
int
ret
=
-
EINVAL
;
int
user_size
=
0
;
/* Get the description of the IOCTL */
if
((
cmd
-
SIOCIWFIRST
)
>=
standard_ioctl_num
)
...
...
@@ -621,8 +653,14 @@ static inline int ioctl_standard_call(struct net_device * dev,
#endif
/* WE_SET_EVENT */
}
else
{
char
*
extra
;
int
extra_size
;
int
user_length
=
0
;
int
err
;
/* Calculate space needed by arguments. Always allocate
* for max space. Easier, and won't last long... */
extra_size
=
descr
->
max_tokens
*
descr
->
token_size
;
/* Check what user space is giving us */
if
(
IW_IS_SET
(
cmd
))
{
/* Check NULL pointer */
...
...
@@ -639,18 +677,29 @@ static inline int ioctl_standard_call(struct net_device * dev,
if
(
iwr
->
u
.
data
.
pointer
==
NULL
)
return
-
EFAULT
;
/* Save user space buffer size for checking */
user_size
=
iwr
->
u
.
data
.
length
;
user_length
=
iwr
->
u
.
data
.
length
;
/* Don't check if user_length > max to allow forward
* compatibility. The test user_length < min is
* implied by the test at the end. */
/* Support for very large requests */
if
((
descr
->
flags
&
IW_DESCR_FLAG_NOMAX
)
&&
(
user_length
>
descr
->
max_tokens
))
{
/* Allow userspace to GET more than max so
* we can support any size GET requests.
* There is still a limit : -ENOMEM. */
extra_size
=
user_length
*
descr
->
token_size
;
}
}
#ifdef WE_IOCTL_DEBUG
printk
(
KERN_DEBUG
"%s (WE) : Malloc %d bytes
\n
"
,
dev
->
name
,
descr
->
max_tokens
*
descr
->
token
_size
);
dev
->
name
,
extra
_size
);
#endif
/* WE_IOCTL_DEBUG */
/* Always allocate for max space. Easier, and won't last
* long... */
extra
=
kmalloc
(
descr
->
max_tokens
*
descr
->
token_size
,
GFP_KERNEL
);
/* Create the kernel buffer */
extra
=
kmalloc
(
extra_size
,
GFP_KERNEL
);
if
(
extra
==
NULL
)
{
return
-
ENOMEM
;
}
...
...
@@ -676,14 +725,11 @@ static inline int ioctl_standard_call(struct net_device * dev,
/* If we have something to return to the user */
if
(
!
ret
&&
IW_IS_GET
(
cmd
))
{
#ifdef WE_STRICT_WRITE
/* Check if there is enough buffer up there */
if
(
user_size
<
iwr
->
u
.
data
.
length
)
{
printk
(
KERN_ERR
"%s (WE) : Buffer for request %04X too small (%d<%d)
\n
"
,
dev
->
name
,
cmd
,
user_size
,
iwr
->
u
.
data
.
length
);
if
(
user_length
<
iwr
->
u
.
data
.
length
)
{
kfree
(
extra
);
return
-
E2BIG
;
}
#endif
/* WE_STRICT_WRITE */
err
=
copy_to_user
(
iwr
->
u
.
data
.
pointer
,
extra
,
iwr
->
u
.
data
.
length
*
...
...
@@ -746,7 +792,7 @@ static inline int ioctl_private_call(struct net_device * dev,
iw_handler
handler
)
{
struct
iwreq
*
iwr
=
(
struct
iwreq
*
)
ifr
;
struct
iw_priv_args
*
descr
=
NULL
;
const
struct
iw_priv_args
*
descr
=
NULL
;
struct
iw_request_info
info
;
int
extra_size
=
0
;
int
i
;
...
...
@@ -786,7 +832,7 @@ static inline int ioctl_private_call(struct net_device * dev,
((
extra_size
+
offset
)
<=
IFNAMSIZ
))
extra_size
=
0
;
}
else
{
/* Size of
s
et arguments */
/* Size of
g
et arguments */
extra_size
=
get_priv_size
(
descr
->
get_args
);
/* Does it fits in iwr ? */
...
...
@@ -856,6 +902,14 @@ static inline int ioctl_private_call(struct net_device * dev,
/* If we have something to return to the user */
if
(
!
ret
&&
IW_IS_GET
(
cmd
))
{
/* Adjust for the actual length if it's variable,
* avoid leaking kernel bits outside. */
if
(
!
(
descr
->
get_args
&
IW_PRIV_SIZE_FIXED
))
{
extra_size
=
adjust_priv_size
(
descr
->
get_args
,
&
(
iwr
->
u
));
}
err
=
copy_to_user
(
iwr
->
u
.
data
.
pointer
,
extra
,
extra_size
);
if
(
err
)
...
...
@@ -1127,9 +1181,25 @@ void wireless_send_event(struct net_device * dev,
* One of the main advantage of centralising spy support here is that
* it becomes much easier to improve and extend it without having to touch
* the drivers. One example is the addition of the Spy-Threshold events.
* Note : IW_WIRELESS_SPY is defined in iw_handler.h
*/
/* ---------------------------------------------------------------- */
/*
* Return the pointer to the spy data in the driver.
* Because this is called on the Rx path via wireless_spy_update(),
* we want it to be efficient...
*/
static
inline
struct
iw_spy_data
*
get_spydata
(
struct
net_device
*
dev
)
{
/* This is the new way */
if
(
dev
->
wireless_data
)
return
(
dev
->
wireless_data
->
spy_data
);
/* This is the old way. Doesn't work for multi-headed drivers.
* It will be removed in the next version of WE. */
return
(
dev
->
priv
+
dev
->
wireless_handlers
->
spy_offset
);
}
/*------------------------------------------------------------------*/
/*
* Standard Wireless Handler : set Spy List
...
...
@@ -1139,16 +1209,30 @@ int iw_handler_set_spy(struct net_device * dev,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
#ifdef IW_WIRELESS_SPY
struct
iw_spy_data
*
spydata
=
(
dev
->
priv
+
dev
->
wireless_handlers
->
spy_offset
);
struct
iw_spy_data
*
spydata
=
get_spydata
(
dev
);
struct
sockaddr
*
address
=
(
struct
sockaddr
*
)
extra
;
if
(
!
dev
->
wireless_data
)
/* Help user know that driver needs updating */
printk
(
KERN_DEBUG
"%s (WE) : Driver using old/buggy spy support, please fix driver !
\n
"
,
dev
->
name
);
/* Make sure driver is not buggy or using the old API */
if
(
!
spydata
)
return
-
EOPNOTSUPP
;
/* Disable spy collection while we copy the addresses.
*
As we don't disable interrupts, we need to do this to avoid races.
*
As we are the only writer, this is good enough
. */
*
While we copy addresses, any call to wireless_spy_update()
*
will NOP. This is OK, as anyway the addresses are changing
. */
spydata
->
spy_number
=
0
;
/* We want to operate without locking, because wireless_spy_update()
* most likely will happen in the interrupt handler, and therefore
* have it own locking constraints and needs performance.
* The rtnl_lock() make sure we don't race with the other iw_handlers.
* This make sure wireless_spy_update() "see" that the spy list
* is temporarily disabled. */
wmb
();
/* Are there are addresses to copy? */
if
(
wrqu
->
data
.
length
>
0
)
{
int
i
;
...
...
@@ -1174,13 +1258,14 @@ int iw_handler_set_spy(struct net_device * dev,
spydata
->
spy_address
[
i
][
5
]);
#endif
/* WE_SPY_DEBUG */
}
/* Make sure above is updated before re-enabling */
wmb
();
/* Enable addresses */
spydata
->
spy_number
=
wrqu
->
data
.
length
;
return
0
;
#else
/* IW_WIRELESS_SPY */
return
-
EOPNOTSUPP
;
#endif
/* IW_WIRELESS_SPY */
}
/*------------------------------------------------------------------*/
...
...
@@ -1192,12 +1277,14 @@ int iw_handler_get_spy(struct net_device * dev,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
#ifdef IW_WIRELESS_SPY
struct
iw_spy_data
*
spydata
=
(
dev
->
priv
+
dev
->
wireless_handlers
->
spy_offset
);
struct
iw_spy_data
*
spydata
=
get_spydata
(
dev
);
struct
sockaddr
*
address
=
(
struct
sockaddr
*
)
extra
;
int
i
;
/* Make sure driver is not buggy or using the old API */
if
(
!
spydata
)
return
-
EOPNOTSUPP
;
wrqu
->
data
.
length
=
spydata
->
spy_number
;
/* Copy addresses. */
...
...
@@ -1214,9 +1301,6 @@ int iw_handler_get_spy(struct net_device * dev,
for
(
i
=
0
;
i
<
spydata
->
spy_number
;
i
++
)
spydata
->
spy_stat
[
i
].
updated
=
0
;
return
0
;
#else
/* IW_WIRELESS_SPY */
return
-
EOPNOTSUPP
;
#endif
/* IW_WIRELESS_SPY */
}
/*------------------------------------------------------------------*/
...
...
@@ -1228,11 +1312,13 @@ int iw_handler_set_thrspy(struct net_device * dev,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
#ifdef IW_WIRELESS_THRSPY
struct
iw_spy_data
*
spydata
=
(
dev
->
priv
+
dev
->
wireless_handlers
->
spy_offset
);
struct
iw_spy_data
*
spydata
=
get_spydata
(
dev
);
struct
iw_thrspy
*
threshold
=
(
struct
iw_thrspy
*
)
extra
;
/* Make sure driver is not buggy or using the old API */
if
(
!
spydata
)
return
-
EOPNOTSUPP
;
/* Just do it */
memcpy
(
&
(
spydata
->
spy_thr_low
),
&
(
threshold
->
low
),
2
*
sizeof
(
struct
iw_quality
));
...
...
@@ -1245,9 +1331,6 @@ int iw_handler_set_thrspy(struct net_device * dev,
#endif
/* WE_SPY_DEBUG */
return
0
;
#else
/* IW_WIRELESS_THRSPY */
return
-
EOPNOTSUPP
;
#endif
/* IW_WIRELESS_THRSPY */
}
/*------------------------------------------------------------------*/
...
...
@@ -1259,22 +1342,20 @@ int iw_handler_get_thrspy(struct net_device * dev,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
#ifdef IW_WIRELESS_THRSPY
struct
iw_spy_data
*
spydata
=
(
dev
->
priv
+
dev
->
wireless_handlers
->
spy_offset
);
struct
iw_spy_data
*
spydata
=
get_spydata
(
dev
);
struct
iw_thrspy
*
threshold
=
(
struct
iw_thrspy
*
)
extra
;
/* Make sure driver is not buggy or using the old API */
if
(
!
spydata
)
return
-
EOPNOTSUPP
;
/* Just do it */
memcpy
(
&
(
threshold
->
low
),
&
(
spydata
->
spy_thr_low
),
2
*
sizeof
(
struct
iw_quality
));
return
0
;
#else
/* IW_WIRELESS_THRSPY */
return
-
EOPNOTSUPP
;
#endif
/* IW_WIRELESS_THRSPY */
}
#ifdef IW_WIRELESS_THRSPY
/*------------------------------------------------------------------*/
/*
* Prepare and send a Spy Threshold event
...
...
@@ -1312,7 +1393,6 @@ static void iw_send_thrspy_event(struct net_device * dev,
/* Send event to user space */
wireless_send_event
(
dev
,
SIOCGIWTHRSPY
,
&
wrqu
,
(
char
*
)
&
threshold
);
}
#endif
/* IW_WIRELESS_THRSPY */
/* ---------------------------------------------------------------- */
/*
...
...
@@ -1325,12 +1405,14 @@ void wireless_spy_update(struct net_device * dev,
unsigned
char
*
address
,
struct
iw_quality
*
wstats
)
{
#ifdef IW_WIRELESS_SPY
struct
iw_spy_data
*
spydata
=
(
dev
->
priv
+
dev
->
wireless_handlers
->
spy_offset
);
struct
iw_spy_data
*
spydata
=
get_spydata
(
dev
);
int
i
;
int
match
=
-
1
;
/* Make sure driver is not buggy or using the old API */
if
(
!
spydata
)
return
;
#ifdef WE_SPY_DEBUG
printk
(
KERN_DEBUG
"wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X
\n
"
,
dev
->
wireless_handlers
->
spy_offset
,
spydata
,
address
[
0
],
address
[
1
],
address
[
2
],
address
[
3
],
address
[
4
],
address
[
5
]);
#endif
/* WE_SPY_DEBUG */
...
...
@@ -1342,7 +1424,7 @@ void wireless_spy_update(struct net_device * dev,
sizeof
(
struct
iw_quality
));
match
=
i
;
}
#ifdef IW_WIRELESS_THRSPY
/* Generate an event if we cross the spy threshold.
* To avoid event storms, we have a simple hysteresis : we generate
* event only when we go under the low threshold or above the
...
...
@@ -1362,8 +1444,6 @@ void wireless_spy_update(struct net_device * dev,
}
}
}
#endif
/* IW_WIRELESS_THRSPY */
#endif
/* IW_WIRELESS_SPY */
}
EXPORT_SYMBOL
(
iw_handler_get_spy
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment