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
620554e4
Commit
620554e4
authored
Jun 19, 2005
by
Christoph Hellwig
Committed by
Jeff Garzik
Jun 27, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] orinoco: wireless API 15 support
(patch from Moustafa Youssef, updated by Jim Carter and Pavel Roskin).
parent
5d558b7f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
547 additions
and
571 deletions
+547
-571
drivers/net/wireless/orinoco.c
drivers/net/wireless/orinoco.c
+547
-571
No files found.
drivers/net/wireless/orinoco.c
View file @
620554e4
...
...
@@ -463,6 +463,7 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
#include <asm/uaccess.h>
...
...
@@ -538,6 +539,10 @@ MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer
| HERMES_EV_WTERR | HERMES_EV_INFO \
| HERMES_EV_INFDROP )
#define MAX_RID_LEN 1024
static
const
struct
iw_handler_def
orinoco_handler_def
;
/********************************************************************/
/* Data tables */
/********************************************************************/
...
...
@@ -605,7 +610,6 @@ struct hermes_rx_descriptor {
/* Function prototypes */
/********************************************************************/
static
int
orinoco_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
);
static
int
__orinoco_program_rids
(
struct
net_device
*
dev
);
static
void
__orinoco_set_multicast_list
(
struct
net_device
*
dev
);
...
...
@@ -1870,55 +1874,6 @@ __orinoco_set_multicast_list(struct net_device *dev)
dev
->
flags
&=
~
IFF_PROMISC
;
}
static
int
orinoco_reconfigure
(
struct
net_device
*
dev
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
struct
hermes
*
hw
=
&
priv
->
hw
;
unsigned
long
flags
;
int
err
=
0
;
if
(
priv
->
broken_disableport
)
{
schedule_work
(
&
priv
->
reset_work
);
return
0
;
}
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
err
=
hermes_disable_port
(
hw
,
0
);
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Unable to disable port while reconfiguring card
\n
"
,
dev
->
name
);
priv
->
broken_disableport
=
1
;
goto
out
;
}
err
=
__orinoco_program_rids
(
dev
);
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Unable to reconfigure card
\n
"
,
dev
->
name
);
goto
out
;
}
err
=
hermes_enable_port
(
hw
,
0
);
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Unable to enable port while reconfiguring card
\n
"
,
dev
->
name
);
goto
out
;
}
out:
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Resetting instead...
\n
"
,
dev
->
name
);
schedule_work
(
&
priv
->
reset_work
);
err
=
0
;
}
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
/* This must be called from user context, without locks held - use
* schedule_work() */
static
void
orinoco_reset
(
struct
net_device
*
dev
)
...
...
@@ -2458,7 +2413,7 @@ struct net_device *alloc_orinocodev(int sizeof_card,
dev
->
watchdog_timeo
=
HZ
;
/* 1 second timeout */
dev
->
get_stats
=
orinoco_get_stats
;
dev
->
get_wireless_stats
=
orinoco_get_wireless_stats
;
dev
->
do_ioctl
=
orinoco_ioctl
;
dev
->
wireless_handlers
=
(
struct
iw_handler_def
*
)
&
orinoco_handler_def
;
dev
->
change_mtu
=
orinoco_change_mtu
;
dev
->
set_multicast_list
=
orinoco_set_multicast_list
;
/* we use the default eth_mac_addr for setting the MAC addr */
...
...
@@ -2491,24 +2446,6 @@ void free_orinocodev(struct net_device *dev)
/* Wireless extensions */
/********************************************************************/
static
int
orinoco_hw_get_bssid
(
struct
orinoco_private
*
priv
,
char
buf
[
ETH_ALEN
])
{
hermes_t
*
hw
=
&
priv
->
hw
;
int
err
=
0
;
unsigned
long
flags
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
err
=
hermes_read_ltv
(
hw
,
USER_BAP
,
HERMES_RID_CURRENTBSSID
,
ETH_ALEN
,
NULL
,
buf
);
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
static
int
orinoco_hw_get_essid
(
struct
orinoco_private
*
priv
,
int
*
active
,
char
buf
[
IW_ESSID_MAX_SIZE
+
1
])
{
...
...
@@ -2634,140 +2571,201 @@ static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
return
0
;
}
static
int
orinoco_ioctl_getiwrange
(
struct
net_device
*
dev
,
struct
iw_point
*
rrq
)
static
int
orinoco_ioctl_getname
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
char
*
name
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
err
=
0
;
int
mode
;
struct
iw_range
range
;
int
numrates
;
int
i
,
k
;
int
err
;
err
=
orinoco_hw_get_bitratelist
(
priv
,
&
numrates
,
NULL
,
0
);
if
(
!
err
&&
(
numrates
>
2
))
strcpy
(
name
,
"IEEE 802.11b"
);
else
strcpy
(
name
,
"IEEE 802.11-DS"
);
return
0
;
}
static
int
orinoco_ioctl_getwap
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
sockaddr
*
ap_addr
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
hermes_t
*
hw
=
&
priv
->
hw
;
int
err
=
0
;
unsigned
long
flags
;
TRACE_ENTER
(
dev
->
name
);
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
if
(
!
access_ok
(
VERIFY_WRITE
,
rrq
->
pointer
,
sizeof
(
range
)))
return
-
EFAULT
;
ap_addr
->
sa_family
=
ARPHRD_ETHER
;
err
=
hermes_read_ltv
(
hw
,
USER_BAP
,
HERMES_RID_CURRENTBSSID
,
ETH_ALEN
,
NULL
,
ap_addr
->
sa_data
);
rrq
->
length
=
sizeof
(
range
);
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
static
int
orinoco_ioctl_setmode
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
u32
*
mode
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
err
=
-
EINPROGRESS
;
/* Call commit handler */
unsigned
long
flags
;
if
(
priv
->
iw_mode
==
*
mode
)
return
0
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
mode
=
priv
->
iw_mode
;
switch
(
*
mode
)
{
case
IW_MODE_ADHOC
:
if
(
!
priv
->
has_ibss
&&
!
priv
->
has_port3
)
err
=
-
EOPNOTSUPP
;
break
;
case
IW_MODE_INFRA
:
break
;
default:
err
=
-
EOPNOTSUPP
;
break
;
}
if
(
err
==
-
EINPROGRESS
)
{
priv
->
iw_mode
=
*
mode
;
set_port_type
(
priv
);
}
orinoco_unlock
(
priv
,
&
flags
);
memset
(
&
range
,
0
,
sizeof
(
range
));
return
err
;
}
static
int
orinoco_ioctl_getmode
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
u32
*
mode
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
/* Much of this shamelessly taken from wvlan_cs.c. No idea
* what it all means -dgibson */
range
.
we_version_compiled
=
WIRELESS_EXT
;
range
.
we_version_source
=
11
;
*
mode
=
priv
->
iw_mode
;
return
0
;
}
range
.
min_nwid
=
range
.
max_nwid
=
0
;
/* We don't use nwids */
static
int
orinoco_ioctl_getiwrange
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
rrq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
err
=
0
;
struct
iw_range
*
range
=
(
struct
iw_range
*
)
extra
;
int
numrates
;
int
i
,
k
;
TRACE_ENTER
(
dev
->
name
);
rrq
->
length
=
sizeof
(
struct
iw_range
);
memset
(
range
,
0
,
sizeof
(
struct
iw_range
));
range
->
we_version_compiled
=
WIRELESS_EXT
;
range
->
we_version_source
=
14
;
/* Set available channels/frequencies */
range
.
num_channels
=
NUM_CHANNELS
;
range
->
num_channels
=
NUM_CHANNELS
;
k
=
0
;
for
(
i
=
0
;
i
<
NUM_CHANNELS
;
i
++
)
{
if
(
priv
->
channel_mask
&
(
1
<<
i
))
{
range
.
freq
[
k
].
i
=
i
+
1
;
range
.
freq
[
k
].
m
=
channel_frequency
[
i
]
*
100000
;
range
.
freq
[
k
].
e
=
1
;
range
->
freq
[
k
].
i
=
i
+
1
;
range
->
freq
[
k
].
m
=
channel_frequency
[
i
]
*
100000
;
range
->
freq
[
k
].
e
=
1
;
k
++
;
}
if
(
k
>=
IW_MAX_FREQUENCIES
)
break
;
}
range
.
num_frequency
=
k
;
range
->
num_frequency
=
k
;
range
->
sensitivity
=
3
;
range
.
sensitivity
=
3
;
if
(
priv
->
has_wep
)
{
range
->
max_encoding_tokens
=
ORINOCO_MAX_KEYS
;
range
->
encoding_size
[
0
]
=
SMALL_KEY_SIZE
;
range
->
num_encoding_sizes
=
1
;
if
((
mode
==
IW_MODE_ADHOC
)
&&
(
priv
->
spy_number
==
0
)){
if
(
priv
->
has_big_wep
)
{
range
->
encoding_size
[
1
]
=
LARGE_KEY_SIZE
;
range
->
num_encoding_sizes
=
2
;
}
}
if
((
priv
->
iw_mode
==
IW_MODE_ADHOC
)
&&
(
priv
->
spy_number
==
0
)){
/* Quality stats meaningless in ad-hoc mode */
range
.
max_qual
.
qual
=
0
;
range
.
max_qual
.
level
=
0
;
range
.
max_qual
.
noise
=
0
;
range
.
avg_qual
.
qual
=
0
;
range
.
avg_qual
.
level
=
0
;
range
.
avg_qual
.
noise
=
0
;
}
else
{
range
.
max_qual
.
qual
=
0x8b
-
0x2f
;
range
.
max_qual
.
level
=
0x2f
-
0x95
-
1
;
range
.
max_qual
.
noise
=
0x2f
-
0x95
-
1
;
range
->
max_qual
.
qual
=
0x8b
-
0x2f
;
range
->
max_qual
.
level
=
0x2f
-
0x95
-
1
;
range
->
max_qual
.
noise
=
0x2f
-
0x95
-
1
;
/* Need to get better values */
range
.
avg_qual
.
qual
=
0x24
;
range
.
avg_qual
.
level
=
0xC2
;
range
.
avg_qual
.
noise
=
0x9E
;
range
->
avg_qual
.
qual
=
0x24
;
range
->
avg_qual
.
level
=
0xC2
;
range
->
avg_qual
.
noise
=
0x9E
;
}
err
=
orinoco_hw_get_bitratelist
(
priv
,
&
numrates
,
range
.
bitrate
,
IW_MAX_BITRATES
);
range
->
bitrate
,
IW_MAX_BITRATES
);
if
(
err
)
return
err
;
range
.
num_bitrates
=
numrates
;
range
->
num_bitrates
=
numrates
;
/* Set an indication of the max TCP throughput in bit/s that we can
* expect using this interface. May be use for QoS stuff...
* Jean II */
if
(
numrates
>
2
)
range
.
throughput
=
5
*
1000
*
1000
;
/* ~5 Mb/s */
if
(
numrates
>
2
)
range
->
throughput
=
5
*
1000
*
1000
;
/* ~5 Mb/s */
else
range
.
throughput
=
1
.
5
*
1000
*
1000
;
/* ~1.5 Mb/s */
range
.
min_rts
=
0
;
range
.
max_rts
=
2347
;
range
.
min_frag
=
256
;
range
.
max_frag
=
2346
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
if
(
priv
->
has_wep
)
{
range
.
max_encoding_tokens
=
ORINOCO_MAX_KEYS
;
range
.
encoding_size
[
0
]
=
SMALL_KEY_SIZE
;
range
.
num_encoding_sizes
=
1
;
if
(
priv
->
has_big_wep
)
{
range
.
encoding_size
[
1
]
=
LARGE_KEY_SIZE
;
range
.
num_encoding_sizes
=
2
;
}
}
else
{
range
.
num_encoding_sizes
=
0
;
range
.
max_encoding_tokens
=
0
;
}
orinoco_unlock
(
priv
,
&
flags
);
range
.
min_pmp
=
0
;
range
.
max_pmp
=
65535000
;
range
.
min_pmt
=
0
;
range
.
max_pmt
=
65535
*
1000
;
/* ??? */
range
.
pmp_flags
=
IW_POWER_PERIOD
;
range
.
pmt_flags
=
IW_POWER_TIMEOUT
;
range
.
pm_capa
=
IW_POWER_PERIOD
|
IW_POWER_TIMEOUT
|
IW_POWER_UNICAST_R
;
range
.
num_txpower
=
1
;
range
.
txpower
[
0
]
=
15
;
/* 15dBm */
range
.
txpower_capa
=
IW_TXPOW_DBM
;
range
.
retry_capa
=
IW_RETRY_LIMIT
|
IW_RETRY_LIFETIME
;
range
.
retry_flags
=
IW_RETRY_LIMIT
;
range
.
r_time_flags
=
IW_RETRY_LIFETIME
;
range
.
min_retry
=
0
;
range
.
max_retry
=
65535
;
/* ??? */
range
.
min_r_time
=
0
;
range
.
max_r_time
=
65535
*
1000
;
/* ??? */
if
(
copy_to_user
(
rrq
->
pointer
,
&
range
,
sizeof
(
range
)))
return
-
EFAULT
;
range
->
throughput
=
1
.
5
*
1000
*
1000
;
/* ~1.5 Mb/s */
range
->
min_rts
=
0
;
range
->
max_rts
=
2347
;
range
->
min_frag
=
256
;
range
->
max_frag
=
2346
;
range
->
min_pmp
=
0
;
range
->
max_pmp
=
65535000
;
range
->
min_pmt
=
0
;
range
->
max_pmt
=
65535
*
1000
;
/* ??? */
range
->
pmp_flags
=
IW_POWER_PERIOD
;
range
->
pmt_flags
=
IW_POWER_TIMEOUT
;
range
->
pm_capa
=
IW_POWER_PERIOD
|
IW_POWER_TIMEOUT
|
IW_POWER_UNICAST_R
;
range
->
retry_capa
=
IW_RETRY_LIMIT
|
IW_RETRY_LIFETIME
;
range
->
retry_flags
=
IW_RETRY_LIMIT
;
range
->
r_time_flags
=
IW_RETRY_LIFETIME
;
range
->
min_retry
=
0
;
range
->
max_retry
=
65535
;
/* ??? */
range
->
min_r_time
=
0
;
range
->
max_r_time
=
65535
*
1000
;
/* ??? */
TRACE_EXIT
(
dev
->
name
);
return
0
;
}
static
int
orinoco_ioctl_setiwencode
(
struct
net_device
*
dev
,
struct
iw_point
*
erq
)
static
int
orinoco_ioctl_setiwencode
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
erq
,
char
*
keybuf
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
index
=
(
erq
->
flags
&
IW_ENCODE_INDEX
)
-
1
;
...
...
@@ -2775,8 +2773,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *er
int
enable
=
priv
->
wep_on
;
int
restricted
=
priv
->
wep_restrict
;
u16
xlen
=
0
;
int
err
=
0
;
char
keybuf
[
ORINOCO_MAX_KEY_SIZE
];
int
err
=
-
EINPROGRESS
;
/* Call commit handler */
unsigned
long
flags
;
if
(
!
priv
->
has_wep
)
...
...
@@ -2789,9 +2786,6 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *er
if
(
(
erq
->
length
>
SMALL_KEY_SIZE
)
&&
!
priv
->
has_big_wep
)
return
-
E2BIG
;
if
(
copy_from_user
(
keybuf
,
erq
->
pointer
,
erq
->
length
))
return
-
EFAULT
;
}
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
...
...
@@ -2865,12 +2859,14 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *er
return
err
;
}
static
int
orinoco_ioctl_getiwencode
(
struct
net_device
*
dev
,
struct
iw_point
*
erq
)
static
int
orinoco_ioctl_getiwencode
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
erq
,
char
*
keybuf
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
index
=
(
erq
->
flags
&
IW_ENCODE_INDEX
)
-
1
;
u16
xlen
=
0
;
char
keybuf
[
ORINOCO_MAX_KEY_SIZE
];
unsigned
long
flags
;
if
(
!
priv
->
has_wep
)
...
...
@@ -2899,51 +2895,47 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *er
memcpy
(
keybuf
,
priv
->
keys
[
index
].
data
,
ORINOCO_MAX_KEY_SIZE
);
orinoco_unlock
(
priv
,
&
flags
);
if
(
erq
->
pointer
)
{
if
(
copy_to_user
(
erq
->
pointer
,
keybuf
,
xlen
))
return
-
EFAULT
;
}
return
0
;
}
static
int
orinoco_ioctl_setessid
(
struct
net_device
*
dev
,
struct
iw_point
*
erq
)
static
int
orinoco_ioctl_setessid
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
erq
,
char
*
essidbuf
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
char
essidbuf
[
IW_ESSID_MAX_SIZE
+
1
];
unsigned
long
flags
;
/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
* anyway... - Jean II */
memset
(
&
essidbuf
,
0
,
sizeof
(
essidbuf
));
if
(
erq
->
flags
)
{
/* iwconfig includes the NUL in the specified length */
if
(
erq
->
length
>
IW_ESSID_MAX_SIZE
+
1
)
return
-
E2BIG
;
if
(
copy_from_user
(
&
essidbuf
,
erq
->
pointer
,
erq
->
length
))
return
-
EFAULT
;
essidbuf
[
IW_ESSID_MAX_SIZE
]
=
'\0'
;
}
/* Hum... Should not use Wireless Extension constant (may change),
* should use our own... - Jean II */
if
(
erq
->
length
>
IW_ESSID_MAX_SIZE
)
return
-
E2BIG
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
memcpy
(
priv
->
desired_essid
,
essidbuf
,
sizeof
(
priv
->
desired_essid
));
/* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
memset
(
priv
->
desired_essid
,
0
,
sizeof
(
priv
->
desired_essid
));
/* If not ANY, get the new ESSID */
if
(
erq
->
flags
)
{
memcpy
(
priv
->
desired_essid
,
essidbuf
,
erq
->
length
);
}
orinoco_unlock
(
priv
,
&
flags
);
return
0
;
return
-
EINPROGRESS
;
/* Call commit handler */
}
static
int
orinoco_ioctl_getessid
(
struct
net_device
*
dev
,
struct
iw_point
*
erq
)
static
int
orinoco_ioctl_getessid
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
erq
,
char
*
essidbuf
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
char
essidbuf
[
IW_ESSID_MAX_SIZE
+
1
];
int
active
;
int
err
=
0
;
unsigned
long
flags
;
...
...
@@ -2957,51 +2949,46 @@ static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
}
else
{
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
memcpy
(
essidbuf
,
priv
->
desired_essid
,
sizeof
(
essidbuf
)
);
memcpy
(
essidbuf
,
priv
->
desired_essid
,
IW_ESSID_MAX_SIZE
+
1
);
orinoco_unlock
(
priv
,
&
flags
);
}
erq
->
flags
=
1
;
erq
->
length
=
strlen
(
essidbuf
)
+
1
;
if
(
erq
->
pointer
)
if
(
copy_to_user
(
erq
->
pointer
,
essidbuf
,
erq
->
length
))
return
-
EFAULT
;
TRACE_EXIT
(
dev
->
name
);
return
0
;
}
static
int
orinoco_ioctl_setnick
(
struct
net_device
*
dev
,
struct
iw_point
*
nrq
)
static
int
orinoco_ioctl_setnick
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
nrq
,
char
*
nickbuf
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
char
nickbuf
[
IW_ESSID_MAX_SIZE
+
1
];
unsigned
long
flags
;
if
(
nrq
->
length
>
IW_ESSID_MAX_SIZE
)
return
-
E2BIG
;
memset
(
nickbuf
,
0
,
sizeof
(
nickbuf
));
if
(
copy_from_user
(
nickbuf
,
nrq
->
pointer
,
nrq
->
length
))
return
-
EFAULT
;
nickbuf
[
nrq
->
length
]
=
'\0'
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
memcpy
(
priv
->
nick
,
nickbuf
,
sizeof
(
priv
->
nick
));
memset
(
priv
->
nick
,
0
,
sizeof
(
priv
->
nick
));
memcpy
(
priv
->
nick
,
nickbuf
,
nrq
->
length
);
orinoco_unlock
(
priv
,
&
flags
);
return
0
;
return
-
EINPROGRESS
;
/* Call commit handler */
}
static
int
orinoco_ioctl_getnick
(
struct
net_device
*
dev
,
struct
iw_point
*
nrq
)
static
int
orinoco_ioctl_getnick
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
nrq
,
char
*
nickbuf
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
char
nickbuf
[
IW_ESSID_MAX_SIZE
+
1
];
unsigned
long
flags
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
...
...
@@ -3012,17 +2999,18 @@ static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
nrq
->
length
=
strlen
(
nickbuf
)
+
1
;
if
(
copy_to_user
(
nrq
->
pointer
,
nickbuf
,
sizeof
(
nickbuf
)))
return
-
EFAULT
;
return
0
;
}
static
int
orinoco_ioctl_setfreq
(
struct
net_device
*
dev
,
struct
iw_freq
*
frq
)
static
int
orinoco_ioctl_setfreq
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_freq
*
frq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
chan
=
-
1
;
unsigned
long
flags
;
int
err
=
-
EINPROGRESS
;
/* Call commit handler */
/* We can only use this in Ad-Hoc demo mode to set the operating
* frequency, or in IBSS mode to set the frequency where the IBSS
...
...
@@ -3055,10 +3043,33 @@ static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
priv
->
channel
=
chan
;
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
static
int
orinoco_ioctl_getfreq
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_freq
*
frq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
tmp
;
/* Locking done in there */
tmp
=
orinoco_hw_get_freq
(
priv
);
if
(
tmp
<
0
)
{
return
tmp
;
}
frq
->
m
=
tmp
;
frq
->
e
=
1
;
return
0
;
}
static
int
orinoco_ioctl_getsens
(
struct
net_device
*
dev
,
struct
iw_param
*
srq
)
static
int
orinoco_ioctl_getsens
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
srq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
hermes_t
*
hw
=
&
priv
->
hw
;
...
...
@@ -3084,7 +3095,10 @@ static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
return
0
;
}
static
int
orinoco_ioctl_setsens
(
struct
net_device
*
dev
,
struct
iw_param
*
srq
)
static
int
orinoco_ioctl_setsens
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
srq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
val
=
srq
->
value
;
...
...
@@ -3101,10 +3115,13 @@ static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
priv
->
ap_density
=
val
;
orinoco_unlock
(
priv
,
&
flags
);
return
0
;
return
-
EINPROGRESS
;
/* Call commit handler */
}
static
int
orinoco_ioctl_setrts
(
struct
net_device
*
dev
,
struct
iw_param
*
rrq
)
static
int
orinoco_ioctl_setrts
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
rrq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
val
=
rrq
->
value
;
...
...
@@ -3122,13 +3139,30 @@ static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
priv
->
rts_thresh
=
val
;
orinoco_unlock
(
priv
,
&
flags
);
return
-
EINPROGRESS
;
/* Call commit handler */
}
static
int
orinoco_ioctl_getrts
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
rrq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
rrq
->
value
=
priv
->
rts_thresh
;
rrq
->
disabled
=
(
rrq
->
value
==
2347
);
rrq
->
fixed
=
1
;
return
0
;
}
static
int
orinoco_ioctl_setfrag
(
struct
net_device
*
dev
,
struct
iw_param
*
frq
)
static
int
orinoco_ioctl_setfrag
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
frq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
err
=
0
;
int
err
=
-
EINPROGRESS
;
/* Call commit handler */
unsigned
long
flags
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
...
...
@@ -3160,11 +3194,14 @@ static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
return
err
;
}
static
int
orinoco_ioctl_getfrag
(
struct
net_device
*
dev
,
struct
iw_param
*
frq
)
static
int
orinoco_ioctl_getfrag
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
frq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
hermes_t
*
hw
=
&
priv
->
hw
;
int
err
=
0
;
int
err
;
u16
val
;
unsigned
long
flags
;
...
...
@@ -3197,10 +3234,12 @@ static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
return
err
;
}
static
int
orinoco_ioctl_setrate
(
struct
net_device
*
dev
,
struct
iw_param
*
rrq
)
static
int
orinoco_ioctl_setrate
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
rrq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
err
=
0
;
int
ratemode
=
-
1
;
int
bitrate
;
/* 100s of kilobits */
int
i
;
...
...
@@ -3236,10 +3275,13 @@ static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
priv
->
bitratemode
=
ratemode
;
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
return
-
EINPROGRESS
;
}
static
int
orinoco_ioctl_getrate
(
struct
net_device
*
dev
,
struct
iw_param
*
rrq
)
static
int
orinoco_ioctl_getrate
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
rrq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
hermes_t
*
hw
=
&
priv
->
hw
;
...
...
@@ -3304,10 +3346,13 @@ static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
return
err
;
}
static
int
orinoco_ioctl_setpower
(
struct
net_device
*
dev
,
struct
iw_param
*
prq
)
static
int
orinoco_ioctl_setpower
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
prq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
err
=
0
;
int
err
=
-
EINPROGRESS
;
/* Call commit handler */
unsigned
long
flags
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
...
...
@@ -3356,7 +3401,10 @@ static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
return
err
;
}
static
int
orinoco_ioctl_getpower
(
struct
net_device
*
dev
,
struct
iw_param
*
prq
)
static
int
orinoco_ioctl_getpower
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
prq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
hermes_t
*
hw
=
&
priv
->
hw
;
...
...
@@ -3404,7 +3452,10 @@ static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
return
err
;
}
static
int
orinoco_ioctl_getretry
(
struct
net_device
*
dev
,
struct
iw_param
*
rrq
)
static
int
orinoco_ioctl_getretry
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_param
*
rrq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
hermes_t
*
hw
=
&
priv
->
hw
;
...
...
@@ -3455,10 +3506,38 @@ static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
return
err
;
}
static
int
orinoco_ioctl_setibssport
(
struct
net_device
*
dev
,
struct
iwreq
*
wrq
)
static
int
orinoco_ioctl_reset
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
info
->
cmd
==
(
SIOCIWFIRSTPRIV
+
0x1
))
{
printk
(
KERN_DEBUG
"%s: Forcing reset!
\n
"
,
dev
->
name
);
/* Firmware reset */
orinoco_reset
(
dev
);
}
else
{
printk
(
KERN_DEBUG
"%s: Force scheduling reset!
\n
"
,
dev
->
name
);
schedule_work
(
&
priv
->
reset_work
);
}
return
0
;
}
static
int
orinoco_ioctl_setibssport
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
val
=
*
(
(
int
*
)
wrq
->
u
.
name
);
int
val
=
*
(
(
int
*
)
extra
);
unsigned
long
flags
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
...
...
@@ -3470,28 +3549,28 @@ static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
set_port_type
(
priv
);
orinoco_unlock
(
priv
,
&
flags
);
return
0
;
return
-
EINPROGRESS
;
/* Call commit handler */
}
static
int
orinoco_ioctl_getibssport
(
struct
net_device
*
dev
,
struct
iwreq
*
wrq
)
static
int
orinoco_ioctl_getibssport
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
*
val
=
(
int
*
)
wrq
->
u
.
name
;
unsigned
long
flags
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
int
*
val
=
(
int
*
)
extra
;
*
val
=
priv
->
ibss_port
;
orinoco_unlock
(
priv
,
&
flags
);
return
0
;
}
static
int
orinoco_ioctl_setport3
(
struct
net_device
*
dev
,
struct
iwreq
*
wrq
)
static
int
orinoco_ioctl_setport3
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
val
=
*
(
(
int
*
)
wrq
->
u
.
name
);
int
val
=
*
(
(
int
*
)
extra
);
int
err
=
0
;
unsigned
long
flags
;
...
...
@@ -3520,51 +3599,131 @@ static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
err
=
-
EINVAL
;
}
if
(
!
err
)
if
(
!
err
)
{
/* Actually update the mode we are using */
set_port_type
(
priv
);
err
=
-
EINPROGRESS
;
}
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
static
int
orinoco_ioctl_getport3
(
struct
net_device
*
dev
,
struct
iwreq
*
wrq
)
static
int
orinoco_ioctl_getport3
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
*
val
=
(
int
*
)
extra
;
*
val
=
priv
->
prefer_port3
;
return
0
;
}
static
int
orinoco_ioctl_setpreamble
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
*
val
=
(
int
*
)
wrq
->
u
.
name
;
unsigned
long
flags
;
int
val
;
if
(
!
priv
->
has_preamble
)
return
-
EOPNOTSUPP
;
/* 802.11b has recently defined some short preamble.
* Basically, the Phy header has been reduced in size.
* This increase performance, especially at high rates
* (the preamble is transmitted at 1Mb/s), unfortunately
* this give compatibility troubles... - Jean II */
val
=
*
(
(
int
*
)
extra
);
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
*
val
=
priv
->
prefer_port3
;
if
(
val
)
priv
->
preamble
=
1
;
else
priv
->
preamble
=
0
;
orinoco_unlock
(
priv
,
&
flags
);
return
-
EINPROGRESS
;
/* Call commit handler */
}
static
int
orinoco_ioctl_getpreamble
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
*
val
=
(
int
*
)
extra
;
if
(
!
priv
->
has_preamble
)
return
-
EOPNOTSUPP
;
*
val
=
priv
->
preamble
;
return
0
;
}
/* ioctl interface to hermes_read_ltv()
* To use with iwpriv, pass the RID as the token argument, e.g.
* iwpriv get_rid [0xfc00]
* At least Wireless Tools 25 is required to use iwpriv.
* For Wireless Tools 25 and 26 append "dummy" are the end. */
static
int
orinoco_ioctl_getrid
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
data
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
hermes_t
*
hw
=
&
priv
->
hw
;
int
rid
=
data
->
flags
;
u16
length
;
int
err
;
unsigned
long
flags
;
/* It's a "get" function, but we don't want users to access the
* WEP key and other raw firmware data */
if
(
!
capable
(
CAP_NET_ADMIN
))
return
-
EPERM
;
if
(
rid
<
0xfc00
||
rid
>
0xffff
)
return
-
EINVAL
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
err
=
hermes_read_ltv
(
hw
,
USER_BAP
,
rid
,
MAX_RID_LEN
,
&
length
,
extra
);
if
(
err
)
goto
out
;
data
->
length
=
min_t
(
u16
,
HERMES_RECLEN_TO_BYTES
(
length
),
MAX_RID_LEN
);
out:
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
/* Spy is used for link quality/strength measurements in Ad-Hoc mode
* Jean II */
static
int
orinoco_ioctl_setspy
(
struct
net_device
*
dev
,
struct
iw_point
*
srq
)
static
int
orinoco_ioctl_setspy
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
srq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
struct
sockaddr
address
[
IW_MAX_SPY
]
;
struct
sockaddr
*
address
=
(
struct
sockaddr
*
)
extra
;
int
number
=
srq
->
length
;
int
i
;
int
err
=
0
;
unsigned
long
flags
;
/* Check the number of addresses */
if
(
number
>
IW_MAX_SPY
)
return
-
E2BIG
;
/* Get the data in the driver */
if
(
srq
->
pointer
)
{
if
(
copy_from_user
(
address
,
srq
->
pointer
,
sizeof
(
struct
sockaddr
)
*
number
))
return
-
EFAULT
;
}
/* Make sure nobody mess with the structure while we do */
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
...
...
@@ -3588,14 +3747,17 @@ static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
/* Now, let the others play */
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
/* Do NOT call commit handler */
return
0
;
}
static
int
orinoco_ioctl_getspy
(
struct
net_device
*
dev
,
struct
iw_point
*
srq
)
static
int
orinoco_ioctl_getspy
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_point
*
srq
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
struct
sockaddr
address
[
IW_MAX_SPY
];
struct
iw_quality
spy_stat
[
IW_MAX_SPY
];
struct
sockaddr
*
address
=
(
struct
sockaddr
*
)
extra
;
int
number
;
int
i
;
unsigned
long
flags
;
...
...
@@ -3604,7 +3766,12 @@ static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
return
-
EBUSY
;
number
=
priv
->
spy_number
;
if
((
number
>
0
)
&&
(
srq
->
pointer
))
{
/* Create address struct */
for
(
i
=
0
;
i
<
number
;
i
++
)
{
memcpy
(
address
[
i
].
sa_data
,
priv
->
spy_address
[
i
],
ETH_ALEN
);
address
[
i
].
sa_family
=
AF_UNIX
;
}
if
(
number
>
0
)
{
/* Create address struct */
for
(
i
=
0
;
i
<
number
;
i
++
)
{
memcpy
(
address
[
i
].
sa_data
,
priv
->
spy_address
[
i
],
...
...
@@ -3615,344 +3782,153 @@ static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
/* In theory, we should disable irqs while copying the stats
* because the rx path might update it in the middle...
* Bah, who care ? - Jean II */
memcpy
(
&
spy_stat
,
priv
->
spy_stat
,
sizeof
(
struct
iw_quality
)
*
IW_MAX_SPY
);
for
(
i
=
0
;
i
<
number
;
i
++
)
priv
->
spy_stat
[
i
].
updated
=
0
;
memcpy
(
extra
+
(
sizeof
(
struct
sockaddr
)
*
number
),
priv
->
spy_stat
,
sizeof
(
struct
iw_quality
)
*
number
);
}
/* Reset updated flags. */
for
(
i
=
0
;
i
<
number
;
i
++
)
priv
->
spy_stat
[
i
].
updated
=
0
;
orinoco_unlock
(
priv
,
&
flags
);
/* Push stuff to user space */
srq
->
length
=
number
;
if
(
copy_to_user
(
srq
->
pointer
,
address
,
sizeof
(
struct
sockaddr
)
*
number
))
return
-
EFAULT
;
if
(
copy_to_user
(
srq
->
pointer
+
(
sizeof
(
struct
sockaddr
)
*
number
),
&
spy_stat
,
sizeof
(
struct
iw_quality
)
*
number
))
return
-
EFAULT
;
return
0
;
}
static
int
orinoco_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
)
/* Commit handler, called after set operations */
static
int
orinoco_ioctl_commit
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
void
*
wrqu
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
struct
iwreq
*
wrq
=
(
struct
iwreq
*
)
rq
;
int
err
=
0
;
int
tmp
;
int
changed
=
0
;
struct
hermes
*
hw
=
&
priv
->
hw
;
unsigned
long
flags
;
int
err
=
0
;
TRACE_ENTER
(
dev
->
name
);
/* In theory, we could allow most of the the SET stuff to be
* done. In practice, the lapse of time at startup when the
* card is not ready is very short, so why bother... Note
* that netif_device_present is different from up/down
* (ifconfig), when the device is not yet up, it is usually
* already ready... Jean II */
if
(
!
netif_device_present
(
dev
))
return
-
ENODEV
;
switch
(
cmd
)
{
case
SIOCGIWNAME
:
strcpy
(
wrq
->
u
.
name
,
"IEEE 802.11-DS"
);
break
;
case
SIOCGIWAP
:
wrq
->
u
.
ap_addr
.
sa_family
=
ARPHRD_ETHER
;
err
=
orinoco_hw_get_bssid
(
priv
,
wrq
->
u
.
ap_addr
.
sa_data
);
break
;
case
SIOCGIWRANGE
:
err
=
orinoco_ioctl_getiwrange
(
dev
,
&
wrq
->
u
.
data
);
break
;
case
SIOCSIWMODE
:
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
switch
(
wrq
->
u
.
mode
)
{
case
IW_MODE_ADHOC
:
if
(
!
(
priv
->
has_ibss
||
priv
->
has_port3
)
)
err
=
-
EINVAL
;
else
{
priv
->
iw_mode
=
IW_MODE_ADHOC
;
changed
=
1
;
}
break
;
case
IW_MODE_INFRA
:
priv
->
iw_mode
=
IW_MODE_INFRA
;
changed
=
1
;
break
;
default:
err
=
-
EINVAL
;
break
;
}
set_port_type
(
priv
);
orinoco_unlock
(
priv
,
&
flags
);
break
;
case
SIOCGIWMODE
:
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
wrq
->
u
.
mode
=
priv
->
iw_mode
;
orinoco_unlock
(
priv
,
&
flags
);
break
;
case
SIOCSIWENCODE
:
err
=
orinoco_ioctl_setiwencode
(
dev
,
&
wrq
->
u
.
encoding
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWENCODE
:
if
(
!
capable
(
CAP_NET_ADMIN
))
{
err
=
-
EPERM
;
break
;
}
err
=
orinoco_ioctl_getiwencode
(
dev
,
&
wrq
->
u
.
encoding
);
break
;
case
SIOCSIWESSID
:
err
=
orinoco_ioctl_setessid
(
dev
,
&
wrq
->
u
.
essid
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWESSID
:
err
=
orinoco_ioctl_getessid
(
dev
,
&
wrq
->
u
.
essid
);
break
;
case
SIOCSIWNICKN
:
err
=
orinoco_ioctl_setnick
(
dev
,
&
wrq
->
u
.
data
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWNICKN
:
err
=
orinoco_ioctl_getnick
(
dev
,
&
wrq
->
u
.
data
);
break
;
case
SIOCGIWFREQ
:
tmp
=
orinoco_hw_get_freq
(
priv
);
if
(
tmp
<
0
)
{
err
=
tmp
;
}
else
{
wrq
->
u
.
freq
.
m
=
tmp
;
wrq
->
u
.
freq
.
e
=
1
;
}
break
;
case
SIOCSIWFREQ
:
err
=
orinoco_ioctl_setfreq
(
dev
,
&
wrq
->
u
.
freq
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWSENS
:
err
=
orinoco_ioctl_getsens
(
dev
,
&
wrq
->
u
.
sens
);
break
;
case
SIOCSIWSENS
:
err
=
orinoco_ioctl_setsens
(
dev
,
&
wrq
->
u
.
sens
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWRTS
:
wrq
->
u
.
rts
.
value
=
priv
->
rts_thresh
;
wrq
->
u
.
rts
.
disabled
=
(
wrq
->
u
.
rts
.
value
==
2347
);
wrq
->
u
.
rts
.
fixed
=
1
;
break
;
case
SIOCSIWRTS
:
err
=
orinoco_ioctl_setrts
(
dev
,
&
wrq
->
u
.
rts
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCSIWFRAG
:
err
=
orinoco_ioctl_setfrag
(
dev
,
&
wrq
->
u
.
frag
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWFRAG
:
err
=
orinoco_ioctl_getfrag
(
dev
,
&
wrq
->
u
.
frag
);
break
;
case
SIOCSIWRATE
:
err
=
orinoco_ioctl_setrate
(
dev
,
&
wrq
->
u
.
bitrate
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWRATE
:
err
=
orinoco_ioctl_getrate
(
dev
,
&
wrq
->
u
.
bitrate
);
break
;
case
SIOCSIWPOWER
:
err
=
orinoco_ioctl_setpower
(
dev
,
&
wrq
->
u
.
power
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCGIWPOWER
:
err
=
orinoco_ioctl_getpower
(
dev
,
&
wrq
->
u
.
power
);
break
;
case
SIOCGIWTXPOW
:
/* The card only supports one tx power, so this is easy */
wrq
->
u
.
txpower
.
value
=
15
;
/* dBm */
wrq
->
u
.
txpower
.
fixed
=
1
;
wrq
->
u
.
txpower
.
disabled
=
0
;
wrq
->
u
.
txpower
.
flags
=
IW_TXPOW_DBM
;
break
;
if
(
!
priv
->
open
)
return
0
;
case
SIOCSIWRETRY
:
err
=
-
EOPNOTSUPP
;
break
;
if
(
priv
->
broken_disableport
)
{
orinoco_reset
(
dev
);
return
0
;
}
case
SIOCGIWRETRY
:
err
=
orinoco_ioctl_getretry
(
dev
,
&
wrq
->
u
.
retry
);
break
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
err
;
case
SIOCSIWSPY
:
err
=
orinoco_ioctl_setspy
(
dev
,
&
wrq
->
u
.
data
);
break
;
err
=
hermes_disable_port
(
hw
,
0
);
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Unable to disable port "
"while reconfiguring card
\n
"
,
dev
->
name
);
priv
->
broken_disableport
=
1
;
goto
out
;
}
case
SIOCGIWSPY
:
err
=
orinoco_ioctl_getspy
(
dev
,
&
wrq
->
u
.
data
);
break
;
err
=
__orinoco_program_rids
(
dev
);
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Unable to reconfigure card
\n
"
,
dev
->
name
);
goto
out
;
}
case
SIOCGIWPRIV
:
if
(
wrq
->
u
.
data
.
pointer
)
{
struct
iw_priv_args
privtab
[]
=
{
{
SIOCIWFIRSTPRIV
+
0x0
,
0
,
0
,
"force_reset"
},
{
SIOCIWFIRSTPRIV
+
0x1
,
0
,
0
,
"card_reset"
},
{
SIOCIWFIRSTPRIV
+
0x2
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
0
,
"set_port3"
},
{
SIOCIWFIRSTPRIV
+
0x3
,
0
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
"get_port3"
},
{
SIOCIWFIRSTPRIV
+
0x4
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
0
,
"set_preamble"
},
{
SIOCIWFIRSTPRIV
+
0x5
,
0
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
"get_preamble"
},
{
SIOCIWFIRSTPRIV
+
0x6
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
0
,
"set_ibssport"
},
{
SIOCIWFIRSTPRIV
+
0x7
,
0
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
"get_ibssport"
},
};
wrq
->
u
.
data
.
length
=
sizeof
(
privtab
)
/
sizeof
(
privtab
[
0
]);
if
(
copy_to_user
(
wrq
->
u
.
data
.
pointer
,
privtab
,
sizeof
(
privtab
)))
err
=
-
EFAULT
;
}
break
;
case
SIOCIWFIRSTPRIV
+
0x0
:
/* force_reset */
case
SIOCIWFIRSTPRIV
+
0x1
:
/* card_reset */
if
(
!
capable
(
CAP_NET_ADMIN
))
{
err
=
-
EPERM
;
break
;
}
printk
(
KERN_DEBUG
"%s: Force scheduling reset!
\n
"
,
dev
->
name
);
err
=
hermes_enable_port
(
hw
,
0
);
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Unable to enable port while reconfiguring card
\n
"
,
dev
->
name
);
goto
out
;
}
out:
if
(
err
)
{
printk
(
KERN_WARNING
"%s: Resetting instead...
\n
"
,
dev
->
name
);
schedule_work
(
&
priv
->
reset_work
);
break
;
case
SIOCIWFIRSTPRIV
+
0x2
:
/* set_port3 */
if
(
!
capable
(
CAP_NET_ADMIN
))
{
err
=
-
EPERM
;
break
;
}
err
=
orinoco_ioctl_setport3
(
dev
,
wrq
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCIWFIRSTPRIV
+
0x3
:
/* get_port3 */
err
=
orinoco_ioctl_getport3
(
dev
,
wrq
);
break
;
case
SIOCIWFIRSTPRIV
+
0x4
:
/* set_preamble */
if
(
!
capable
(
CAP_NET_ADMIN
))
{
err
=
-
EPERM
;
break
;
}
/* 802.11b has recently defined some short preamble.
* Basically, the Phy header has been reduced in size.
* This increase performance, especially at high rates
* (the preamble is transmitted at 1Mb/s), unfortunately
* this give compatibility troubles... - Jean II */
if
(
priv
->
has_preamble
)
{
int
val
=
*
(
(
int
*
)
wrq
->
u
.
name
);
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
if
(
val
)
priv
->
preamble
=
1
;
else
priv
->
preamble
=
0
;
orinoco_unlock
(
priv
,
&
flags
);
changed
=
1
;
}
else
err
=
-
EOPNOTSUPP
;
break
;
err
=
0
;
}
case
SIOCIWFIRSTPRIV
+
0x5
:
/* get_preamble */
if
(
priv
->
has_preamble
)
{
int
*
val
=
(
int
*
)
wrq
->
u
.
name
;
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
*
val
=
priv
->
preamble
;
orinoco_unlock
(
priv
,
&
flags
);
}
else
err
=
-
EOPNOTSUPP
;
break
;
case
SIOCIWFIRSTPRIV
+
0x6
:
/* set_ibssport */
if
(
!
capable
(
CAP_NET_ADMIN
))
{
err
=
-
EPERM
;
break
;
}
static
const
struct
iw_priv_args
orinoco_privtab
[]
=
{
{
SIOCIWFIRSTPRIV
+
0x0
,
0
,
0
,
"force_reset"
},
{
SIOCIWFIRSTPRIV
+
0x1
,
0
,
0
,
"card_reset"
},
{
SIOCIWFIRSTPRIV
+
0x2
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
0
,
"set_port3"
},
{
SIOCIWFIRSTPRIV
+
0x3
,
0
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
"get_port3"
},
{
SIOCIWFIRSTPRIV
+
0x4
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
0
,
"set_preamble"
},
{
SIOCIWFIRSTPRIV
+
0x5
,
0
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
"get_preamble"
},
{
SIOCIWFIRSTPRIV
+
0x6
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
0
,
"set_ibssport"
},
{
SIOCIWFIRSTPRIV
+
0x7
,
0
,
IW_PRIV_TYPE_INT
|
IW_PRIV_SIZE_FIXED
|
1
,
"get_ibssport"
},
{
SIOCIWFIRSTPRIV
+
0x9
,
0
,
IW_PRIV_TYPE_BYTE
|
MAX_RID_LEN
,
"get_rid"
},
};
err
=
orinoco_ioctl_setibssport
(
dev
,
wrq
);
if
(
!
err
)
changed
=
1
;
break
;
case
SIOCIWFIRSTPRIV
+
0x7
:
/* get_ibssport */
err
=
orinoco_ioctl_getibssport
(
dev
,
wrq
);
break
;
/*
* Structures to export the Wireless Handlers
*/
default:
err
=
-
EOPNOTSUPP
;
}
if
(
!
err
&&
changed
&&
netif_running
(
dev
))
{
err
=
orinoco_reconfigure
(
dev
);
}
static
const
iw_handler
orinoco_handler
[]
=
{
[
SIOCSIWCOMMIT
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_commit
,
[
SIOCGIWNAME
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getname
,
[
SIOCSIWFREQ
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setfreq
,
[
SIOCGIWFREQ
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getfreq
,
[
SIOCSIWMODE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setmode
,
[
SIOCGIWMODE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getmode
,
[
SIOCSIWSENS
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setsens
,
[
SIOCGIWSENS
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getsens
,
[
SIOCGIWRANGE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getiwrange
,
[
SIOCSIWSPY
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setspy
,
[
SIOCGIWSPY
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getspy
,
[
SIOCGIWAP
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getwap
,
[
SIOCSIWESSID
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setessid
,
[
SIOCGIWESSID
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getessid
,
[
SIOCSIWNICKN
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setnick
,
[
SIOCGIWNICKN
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getnick
,
[
SIOCSIWRATE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setrate
,
[
SIOCGIWRATE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getrate
,
[
SIOCSIWRTS
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setrts
,
[
SIOCGIWRTS
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getrts
,
[
SIOCSIWFRAG
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setfrag
,
[
SIOCGIWFRAG
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getfrag
,
[
SIOCGIWRETRY
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getretry
,
[
SIOCSIWENCODE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setiwencode
,
[
SIOCGIWENCODE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getiwencode
,
[
SIOCSIWPOWER
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setpower
,
[
SIOCGIWPOWER
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getpower
,
};
TRACE_EXIT
(
dev
->
name
);
return
err
;
}
/*
Added typecasting since we no longer use iwreq_data -- Moustafa
*/
static
const
iw_handler
orinoco_private_handler
[]
=
{
[
0
]
(
iw_handler
)
orinoco_ioctl_reset
,
[
1
]
(
iw_handler
)
orinoco_ioctl_reset
,
[
2
]
(
iw_handler
)
orinoco_ioctl_setport3
,
[
3
]
(
iw_handler
)
orinoco_ioctl_getport3
,
[
4
]
(
iw_handler
)
orinoco_ioctl_setpreamble
,
[
5
]
(
iw_handler
)
orinoco_ioctl_getpreamble
,
[
6
]
(
iw_handler
)
orinoco_ioctl_setibssport
,
[
7
]
(
iw_handler
)
orinoco_ioctl_getibssport
,
[
9
]
(
iw_handler
)
orinoco_ioctl_getrid
,
};
static
const
struct
iw_handler_def
orinoco_handler_def
=
{
.
num_standard
=
ARRAY_SIZE
(
orinoco_handler
),
.
num_private
=
ARRAY_SIZE
(
orinoco_private_handler
),
.
num_private_args
=
ARRAY_SIZE
(
orinoco_privtab
),
.
standard
=
orinoco_handler
,
.
private
=
orinoco_private_handler
,
.
private_args
=
orinoco_privtab
,
};
/********************************************************************/
/* Debugging */
...
...
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