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
16739b06
Commit
16739b06
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: manual roaming for Symbol and Intersilfirmware
Patch from Pavel Roskin
parent
1fab2e8b
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
174 additions
and
0 deletions
+174
-0
drivers/net/wireless/orinoco.c
drivers/net/wireless/orinoco.c
+169
-0
drivers/net/wireless/orinoco.h
drivers/net/wireless/orinoco.h
+5
-0
No files found.
drivers/net/wireless/orinoco.c
View file @
16739b06
...
@@ -1247,6 +1247,75 @@ static void print_linkstatus(struct net_device *dev, u16 status)
...
@@ -1247,6 +1247,75 @@ static void print_linkstatus(struct net_device *dev, u16 status)
dev
->
name
,
s
,
status
);
dev
->
name
,
s
,
status
);
}
}
/* Search scan results for requested BSSID, join it if found */
static
void
orinoco_join_ap
(
struct
net_device
*
dev
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
struct
hermes
*
hw
=
&
priv
->
hw
;
int
err
;
unsigned
long
flags
;
struct
join_req
{
u8
bssid
[
ETH_ALEN
];
u16
channel
;
}
__attribute__
((
packed
))
req
;
const
int
atom_len
=
offsetof
(
struct
prism2_scan_apinfo
,
atim
);
struct
prism2_scan_apinfo
*
atom
;
int
offset
=
4
;
u8
*
buf
;
u16
len
;
/* Allocate buffer for scan results */
buf
=
kmalloc
(
MAX_SCAN_LEN
,
GFP_KERNEL
);
if
(
!
buf
)
return
;
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
goto
out
;
/* Sanity checks in case user changed something in the meantime */
if
(
!
priv
->
bssid_fixed
)
goto
out
;
if
(
strlen
(
priv
->
desired_essid
)
==
0
)
goto
out
;
/* Read scan results from the firmware */
err
=
hermes_read_ltv
(
hw
,
USER_BAP
,
HERMES_RID_SCANRESULTSTABLE
,
MAX_SCAN_LEN
,
&
len
,
buf
);
if
(
err
)
{
printk
(
KERN_ERR
"%s: Cannot read scan results
\n
"
,
dev
->
name
);
goto
out
;
}
len
=
HERMES_RECLEN_TO_BYTES
(
len
);
/* Go through the scan results looking for the channel of the AP
* we were requested to join */
for
(;
offset
+
atom_len
<=
len
;
offset
+=
atom_len
)
{
atom
=
(
struct
prism2_scan_apinfo
*
)
(
buf
+
offset
);
if
(
memcmp
(
&
atom
->
bssid
,
priv
->
desired_bssid
,
ETH_ALEN
)
==
0
)
goto
found
;
}
DEBUG
(
1
,
"%s: Requested AP not found in scan results
\n
"
,
dev
->
name
);
goto
out
;
found:
memcpy
(
req
.
bssid
,
priv
->
desired_bssid
,
ETH_ALEN
);
req
.
channel
=
atom
->
channel
;
/* both are little-endian */
err
=
HERMES_WRITE_RECORD
(
hw
,
USER_BAP
,
HERMES_RID_CNFJOINREQUEST
,
&
req
);
if
(
err
)
printk
(
KERN_ERR
"%s: Error issuing join request
\n
"
,
dev
->
name
);
out:
kfree
(
buf
);
orinoco_unlock
(
priv
,
&
flags
);
}
static
void
__orinoco_ev_info
(
struct
net_device
*
dev
,
hermes_t
*
hw
)
static
void
__orinoco_ev_info
(
struct
net_device
*
dev
,
hermes_t
*
hw
)
{
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
...
@@ -1477,6 +1546,36 @@ static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
...
@@ -1477,6 +1546,36 @@ static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
return
err
;
return
err
;
}
}
/* Set fixed AP address */
static
int
__orinoco_hw_set_wap
(
struct
orinoco_private
*
priv
)
{
int
roaming_flag
;
int
err
=
0
;
hermes_t
*
hw
=
&
priv
->
hw
;
switch
(
priv
->
firmware_type
)
{
case
FIRMWARE_TYPE_AGERE
:
/* not supported */
break
;
case
FIRMWARE_TYPE_INTERSIL
:
if
(
priv
->
bssid_fixed
)
roaming_flag
=
2
;
else
roaming_flag
=
1
;
err
=
hermes_write_wordrec
(
hw
,
USER_BAP
,
HERMES_RID_CNFROAMINGMODE
,
roaming_flag
);
break
;
case
FIRMWARE_TYPE_SYMBOL
:
err
=
HERMES_WRITE_RECORD
(
hw
,
USER_BAP
,
HERMES_RID_CNFMANDATORYBSSID_SYMBOL
,
&
priv
->
desired_bssid
);
break
;
}
return
err
;
}
/* Change the WEP keys and/or the current keys. Can be called
/* Change the WEP keys and/or the current keys. Can be called
* either from __orinoco_hw_setup_wep() or directly from
* either from __orinoco_hw_setup_wep() or directly from
* orinoco_ioctl_setiwencode(). In the later case the association
* orinoco_ioctl_setiwencode(). In the later case the association
...
@@ -1662,6 +1761,13 @@ static int __orinoco_program_rids(struct net_device *dev)
...
@@ -1662,6 +1761,13 @@ static int __orinoco_program_rids(struct net_device *dev)
}
}
}
}
/* Set the desired BSSID */
err
=
__orinoco_hw_set_wap
(
priv
);
if
(
err
)
{
printk
(
KERN_ERR
"%s: Error %d setting AP address
\n
"
,
dev
->
name
,
err
);
return
err
;
}
/* Set the desired ESSID */
/* Set the desired ESSID */
idbuf
.
len
=
cpu_to_le16
(
strlen
(
priv
->
desired_essid
));
idbuf
.
len
=
cpu_to_le16
(
strlen
(
priv
->
desired_essid
));
memcpy
(
&
idbuf
.
val
,
priv
->
desired_essid
,
sizeof
(
idbuf
.
val
));
memcpy
(
&
idbuf
.
val
,
priv
->
desired_essid
,
sizeof
(
idbuf
.
val
));
...
@@ -2432,6 +2538,7 @@ struct net_device *alloc_orinocodev(int sizeof_card,
...
@@ -2432,6 +2538,7 @@ struct net_device *alloc_orinocodev(int sizeof_card,
* before anything else touches the
* before anything else touches the
* hardware */
* hardware */
INIT_WORK
(
&
priv
->
reset_work
,
(
void
(
*
)(
void
*
))
orinoco_reset
,
dev
);
INIT_WORK
(
&
priv
->
reset_work
,
(
void
(
*
)(
void
*
))
orinoco_reset
,
dev
);
INIT_WORK
(
&
priv
->
join_work
,
(
void
(
*
)(
void
*
))
orinoco_join_ap
,
dev
);
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
priv
->
last_linkstatus
=
0xffff
;
priv
->
last_linkstatus
=
0xffff
;
...
@@ -2593,6 +2700,67 @@ static int orinoco_ioctl_getname(struct net_device *dev,
...
@@ -2593,6 +2700,67 @@ static int orinoco_ioctl_getname(struct net_device *dev,
return
0
;
return
0
;
}
}
static
int
orinoco_ioctl_setwap
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
sockaddr
*
ap_addr
,
char
*
extra
)
{
struct
orinoco_private
*
priv
=
netdev_priv
(
dev
);
int
err
=
-
EINPROGRESS
;
/* Call commit handler */
unsigned
long
flags
;
static
const
u8
off_addr
[]
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
static
const
u8
any_addr
[]
=
{
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
};
if
(
orinoco_lock
(
priv
,
&
flags
)
!=
0
)
return
-
EBUSY
;
/* Enable automatic roaming - no sanity checks are needed */
if
(
memcmp
(
&
ap_addr
->
sa_data
,
off_addr
,
ETH_ALEN
)
==
0
||
memcmp
(
&
ap_addr
->
sa_data
,
any_addr
,
ETH_ALEN
)
==
0
)
{
priv
->
bssid_fixed
=
0
;
memset
(
priv
->
desired_bssid
,
0
,
ETH_ALEN
);
/* "off" means keep existing connection */
if
(
ap_addr
->
sa_data
[
0
]
==
0
)
{
__orinoco_hw_set_wap
(
priv
);
err
=
0
;
}
goto
out
;
}
if
(
priv
->
firmware_type
==
FIRMWARE_TYPE_AGERE
)
{
printk
(
KERN_WARNING
"%s: Lucent/Agere firmware doesn't "
"support manual roaming
\n
"
,
dev
->
name
);
err
=
-
EOPNOTSUPP
;
goto
out
;
}
if
(
priv
->
iw_mode
!=
IW_MODE_INFRA
)
{
printk
(
KERN_WARNING
"%s: Manual roaming supported only in "
"managed mode
\n
"
,
dev
->
name
);
err
=
-
EOPNOTSUPP
;
goto
out
;
}
/* Intersil firmware hangs without Desired ESSID */
if
(
priv
->
firmware_type
==
FIRMWARE_TYPE_INTERSIL
&&
strlen
(
priv
->
desired_essid
)
==
0
)
{
printk
(
KERN_WARNING
"%s: Desired ESSID must be set for "
"manual roaming
\n
"
,
dev
->
name
);
err
=
-
EOPNOTSUPP
;
goto
out
;
}
/* Finally, enable manual roaming */
priv
->
bssid_fixed
=
1
;
memcpy
(
priv
->
desired_bssid
,
&
ap_addr
->
sa_data
,
ETH_ALEN
);
out:
orinoco_unlock
(
priv
,
&
flags
);
return
err
;
}
static
int
orinoco_ioctl_getwap
(
struct
net_device
*
dev
,
static
int
orinoco_ioctl_getwap
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
struct
iw_request_info
*
info
,
struct
sockaddr
*
ap_addr
,
struct
sockaddr
*
ap_addr
,
...
@@ -3890,6 +4058,7 @@ static const iw_handler orinoco_handler[] = {
...
@@ -3890,6 +4058,7 @@ static const iw_handler orinoco_handler[] = {
[
SIOCGIWRANGE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getiwrange
,
[
SIOCGIWRANGE
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getiwrange
,
[
SIOCSIWSPY
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setspy
,
[
SIOCSIWSPY
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setspy
,
[
SIOCGIWSPY
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getspy
,
[
SIOCGIWSPY
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getspy
,
[
SIOCSIWAP
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setwap
,
[
SIOCGIWAP
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getwap
,
[
SIOCGIWAP
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getwap
,
[
SIOCSIWESSID
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setessid
,
[
SIOCSIWESSID
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_setessid
,
[
SIOCGIWESSID
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getessid
,
[
SIOCGIWESSID
-
SIOCIWFIRST
]
(
iw_handler
)
orinoco_ioctl_getessid
,
...
...
drivers/net/wireless/orinoco.h
View file @
16739b06
...
@@ -22,6 +22,8 @@
...
@@ -22,6 +22,8 @@
#define WIRELESS_SPY // enable iwspy support
#define WIRELESS_SPY // enable iwspy support
#define MAX_SCAN_LEN 4096
#define ORINOCO_MAX_KEY_SIZE 14
#define ORINOCO_MAX_KEY_SIZE 14
#define ORINOCO_MAX_KEYS 4
#define ORINOCO_MAX_KEYS 4
...
@@ -48,6 +50,7 @@ struct orinoco_private {
...
@@ -48,6 +50,7 @@ struct orinoco_private {
/* driver state */
/* driver state */
int
open
;
int
open
;
u16
last_linkstatus
;
u16
last_linkstatus
;
struct
work_struct
join_work
;
/* Net device stuff */
/* Net device stuff */
struct
net_device
*
ndev
;
struct
net_device
*
ndev
;
...
@@ -84,6 +87,8 @@ struct orinoco_private {
...
@@ -84,6 +87,8 @@ struct orinoco_private {
int
bitratemode
;
int
bitratemode
;
char
nick
[
IW_ESSID_MAX_SIZE
+
1
];
char
nick
[
IW_ESSID_MAX_SIZE
+
1
];
char
desired_essid
[
IW_ESSID_MAX_SIZE
+
1
];
char
desired_essid
[
IW_ESSID_MAX_SIZE
+
1
];
char
desired_bssid
[
ETH_ALEN
];
int
bssid_fixed
;
u16
frag_thresh
,
mwo_robust
;
u16
frag_thresh
,
mwo_robust
;
u16
channel
;
u16
channel
;
u16
ap_density
,
rts_thresh
;
u16
ap_density
,
rts_thresh
;
...
...
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