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
45ed1c5a
Commit
45ed1c5a
authored
Jun 27, 2003
by
Arnaldo Carvalho de Melo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
o wl3501: initial batch of support for wireless extensions and ethtool
parent
73fca214
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
222 additions
and
65 deletions
+222
-65
drivers/net/wireless/Kconfig
drivers/net/wireless/Kconfig
+2
-0
drivers/net/wireless/wl3501.h
drivers/net/wireless/wl3501.h
+6
-11
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/wl3501_cs.c
+214
-54
No files found.
drivers/net/wireless/Kconfig
View file @
45ed1c5a
...
@@ -301,6 +301,8 @@ config PCMCIA_WL3501
...
@@ -301,6 +301,8 @@ config PCMCIA_WL3501
depends on NET_RADIO && EXPERIMENTAL && PCMCIA
depends on NET_RADIO && EXPERIMENTAL && PCMCIA
---help---
---help---
A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet.
A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet.
It has basic support for Linux wireless extensions and initial
micro support for ethtool.
# yes, this works even when no drivers are selected
# yes, this works even when no drivers are selected
config NET_WIRELESS
config NET_WIRELESS
...
...
drivers/net/wireless/wl3501.h
View file @
45ed1c5a
...
@@ -63,8 +63,8 @@ enum wl3501_signals {
...
@@ -63,8 +63,8 @@ enum wl3501_signals {
};
};
enum
wl3501_net_type
{
enum
wl3501_net_type
{
WL3501_NET_TYPE_INFRA
STRUCTURE
,
WL3501_NET_TYPE_INFRA
,
WL3501_NET_TYPE_
INDEPENDENT
,
WL3501_NET_TYPE_
ADHOC
,
WL3501_NET_TYPE_ANY_BSS
,
WL3501_NET_TYPE_ANY_BSS
,
};
};
...
@@ -84,12 +84,6 @@ enum wl3501_sys_type {
...
@@ -84,12 +84,6 @@ enum wl3501_sys_type {
WL3501_SYS_TYPE_SHARE_KEY
,
WL3501_SYS_TYPE_SHARE_KEY
,
};
};
enum
wl3501_pkt_type
{
WL3501_PKT_TYPE_ETHERII
,
WL3501_PKT_TYPE_ETHER802_3E
,
WL3501_PKT_TYPE_ETHER802_3F
,
};
enum
wl3501_status
{
enum
wl3501_status
{
WL3501_STATUS_SUCCESS
,
WL3501_STATUS_SUCCESS
,
WL3501_STATUS_INVALID
,
WL3501_STATUS_INVALID
,
...
@@ -429,10 +423,10 @@ struct wl3501_card {
...
@@ -429,10 +423,10 @@ struct wl3501_card {
u16
esbq_confirm
;
u16
esbq_confirm
;
struct
wl3501_mac_addr
bssid
;
struct
wl3501_mac_addr
bssid
;
u8
llc_type
;
u8
llc_type
;
enum
wl3501_net_type
net_type
;
int
net_type
;
u8
essid
[
34
];
u8
essid
[
34
];
u8
keep_essid
[
34
];
u8
keep_essid
[
34
];
u8
ether_type
;
int
ether_type
;
u8
chan
;
u8
chan
;
u8
def_chan
;
u8
def_chan
;
u16
start_seg
;
u16
start_seg
;
...
@@ -447,6 +441,7 @@ struct wl3501_card {
...
@@ -447,6 +441,7 @@ struct wl3501_card {
u8
version
[
2
];
u8
version
[
2
];
struct
net_device_stats
stats
;
struct
net_device_stats
stats
;
struct
iw_statistics
wstats
;
struct
iw_statistics
wstats
;
struct
iw_spy_data
spy_data
;
struct
dev_node_t
node
;
struct
dev_node_t
node
;
};
};
...
@@ -476,7 +471,7 @@ struct wl3501_ioctl_parm {
...
@@ -476,7 +471,7 @@ struct wl3501_ioctl_parm {
};
};
enum
wl3501_ioctl_cmd
{
enum
wl3501_ioctl_cmd
{
WL3501_IOCTL_CMD_GET_PARAMETER
,
WL3501_IOCTL_CMD_GET_PARAMETER
=
SIOCIWFIRSTPRIV
,
WL3501_IOCTL_CMD_SET_PARAMETER
,
WL3501_IOCTL_CMD_SET_PARAMETER
,
WL3501_IOCTL_CMD_WRITE_FLASH
,
WL3501_IOCTL_CMD_WRITE_FLASH
,
WL3501_IOCTL_CMD_SET_RESET
,
WL3501_IOCTL_CMD_SET_RESET
,
...
...
drivers/net/wireless/wl3501_cs.c
View file @
45ed1c5a
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
* Ported to 2.2, 2.4 & 2.5 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* Ported to 2.2, 2.4 & 2.5 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* Wireless extensions in 2.4 by Gustavo Niemeyer <niemeyer@conectiva.com>
* Wireless extensions in 2.4 by Gustavo Niemeyer <niemeyer@conectiva.com>
*
*
* References:
* References
used by Fox Chen while writing the original driver for 2.0.30
:
*
*
* 1. WL24xx packet drivers (tooasm.asm)
* 1. WL24xx packet drivers (tooasm.asm)
* 2. Access Point Firmware Interface Specification for IEEE 802.11 SUTRO
* 2. Access Point Firmware Interface Specification for IEEE 802.11 SUTRO
...
@@ -24,30 +24,27 @@
...
@@ -24,30 +24,27 @@
* 173 KiB/s in TCP.
* 173 KiB/s in TCP.
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/in.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/fcntl.h>
#include <asm/system.h>
#include <linux/if_arp.h>
#include <asm/bitops.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/skbuff.h>
#include <linux/
if_arp
.h>
#include <linux/
slab
.h>
#include <linux/
ioport
.h>
#include <linux/
string
.h>
#include <linux/
fcntl
.h>
#include <linux/
timer
.h>
#include <linux/wireless.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <pcmcia/version.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cs.h>
...
@@ -55,6 +52,10 @@
...
@@ -55,6 +52,10 @@
#include <pcmcia/cisreg.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
#include <pcmcia/ds.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include "wl3501.h"
#include "wl3501.h"
/*
/*
...
@@ -95,14 +96,6 @@ static u8 wl3501_fpage[] = {
...
@@ -95,14 +96,6 @@ static u8 wl3501_fpage[] = {
static
unsigned
long
wl3501_irq_mask
=
0xdeb8
;
static
unsigned
long
wl3501_irq_mask
=
0xdeb8
;
static
int
wl3501_irq_list
[
4
]
=
{
-
1
};
static
int
wl3501_irq_list
[
4
]
=
{
-
1
};
MODULE_PARM
(
wl3501_irq_mask
,
"i"
);
MODULE_PARM
(
wl3501_irq_list
,
"1-4i"
);
MODULE_AUTHOR
(
"Fox Chen <mhchen@golf.ccl.itri.org.tw>, "
"Arnaldo Carvalho de Melo <acme@conectiva.com.br>,"
"Gustavo Niemeyer <niemeyer@conectiva.com>"
);
MODULE_DESCRIPTION
(
"Planet wl3501 wireless driver"
);
MODULE_LICENSE
(
"GPL"
);
/*
/*
* The event() function is this driver's Card Services event handler. It will
* The event() function is this driver's Card Services event handler. It will
* be called by Card Services when an appropriate card status event is
* be called by Card Services when an appropriate card status event is
...
@@ -676,10 +669,10 @@ static int wl3501_mgmt_scan(struct wl3501_card *this, u16 chan_time)
...
@@ -676,10 +669,10 @@ static int wl3501_mgmt_scan(struct wl3501_card *this, u16 chan_time)
signal
.
min_chan_time
=
chan_time
;
signal
.
min_chan_time
=
chan_time
;
signal
.
max_chan_time
=
chan_time
;
signal
.
max_chan_time
=
chan_time
;
if
(
this
->
net_type
==
WL3501_NET_TYPE_INFRASTRUCTURE
)
if
(
this
->
net_type
==
IW_MODE_INFRA
)
signal
.
bss_type
=
WL3501_NET_TYPE_INFRA
STRUCTURE
;
signal
.
bss_type
=
WL3501_NET_TYPE_INFRA
;
else
else
signal
.
bss_type
=
WL3501_NET_TYPE_
INDEPENDENT
;
signal
.
bss_type
=
WL3501_NET_TYPE_
ADHOC
;
this
->
bss_cnt
=
this
->
join_sta_bss
=
0
;
this
->
bss_cnt
=
this
->
join_sta_bss
=
0
;
...
@@ -726,7 +719,8 @@ static int wl3501_mgmt_start(struct wl3501_card *this)
...
@@ -726,7 +719,8 @@ static int wl3501_mgmt_start(struct wl3501_card *this)
signal
.
sig_id
=
WL3501_SIG_START_REQ
;
signal
.
sig_id
=
WL3501_SIG_START_REQ
;
memcpy
((
char
*
)
signal
.
ssid
,
(
char
*
)
this
->
essid
,
34
);
memcpy
((
char
*
)
signal
.
ssid
,
(
char
*
)
this
->
essid
,
34
);
memcpy
((
char
*
)
this
->
keep_essid
,
(
char
*
)
this
->
essid
,
34
);
memcpy
((
char
*
)
this
->
keep_essid
,
(
char
*
)
this
->
essid
,
34
);
signal
.
bss_type
=
WL3501_NET_TYPE_INDEPENDENT
;
signal
.
bss_type
=
this
->
net_type
=
IW_MODE_INFRA
?
WL3501_NET_TYPE_INFRA
:
WL3501_NET_TYPE_INFRA
;
signal
.
beacon_period
=
400
;
signal
.
beacon_period
=
400
;
signal
.
dtim_period
=
1
;
signal
.
dtim_period
=
1
;
signal
.
phy_pset
[
0
]
=
3
;
signal
.
phy_pset
[
0
]
=
3
;
...
@@ -777,11 +771,11 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
...
@@ -777,11 +771,11 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
(
char
*
)
&
(
signal
.
beacon_period
),
73
);
(
char
*
)
&
(
signal
.
beacon_period
),
73
);
this
->
bss_cnt
++
;
this
->
bss_cnt
++
;
}
}
}
else
if
((
this
->
net_type
==
WL3501_NET_TYPE_INFRASTRUCTURE
&&
}
else
if
((
this
->
net_type
==
IW_MODE_INFRA
&&
(
signal
.
cap_info
&
0x01
))
||
(
signal
.
cap_info
&
0x01
))
||
(
this
->
net_type
==
WL3501_NET_TYPE_INDEPENDENT
&&
(
this
->
net_type
==
IW_MODE_ADHOC
&&
(
signal
.
cap_info
&
0x02
))
||
(
signal
.
cap_info
&
0x02
))
||
this
->
net_type
==
WL3501_NET_TYPE_ANY_BSS
)
{
this
->
net_type
==
IW_MODE_AUTO
)
{
if
(
!
this
->
essid
[
1
])
if
(
!
this
->
essid
[
1
])
matchflag
=
1
;
matchflag
=
1
;
else
if
(
this
->
essid
[
1
]
==
3
&&
else
if
(
this
->
essid
[
1
]
==
3
&&
...
@@ -820,7 +814,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
...
@@ -820,7 +814,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
break
;
break
;
this
->
join_sta_bss
=
j
;
this
->
join_sta_bss
=
j
;
if
(
this
->
join_sta_bss
==
this
->
bss_cnt
)
{
if
(
this
->
join_sta_bss
==
this
->
bss_cnt
)
{
if
(
this
->
net_type
==
WL3501_NET_TYPE_INFRASTRUCTURE
)
if
(
this
->
net_type
==
IW_MODE_INFRA
)
wl3501_mgmt_scan
(
this
,
100
);
wl3501_mgmt_scan
(
this
,
100
);
else
{
else
{
this
->
adhoc_times
++
;
this
->
adhoc_times
++
;
...
@@ -886,7 +880,7 @@ static u16 wl3501_receive(struct wl3501_card *this, u8 *bf, u16 size)
...
@@ -886,7 +880,7 @@ static u16 wl3501_receive(struct wl3501_card *this, u8 *bf, u16 size)
wl3501_get_from_wla
(
this
,
this
->
start_seg
+
2
,
wl3501_get_from_wla
(
this
,
this
->
start_seg
+
2
,
&
next_addr
,
sizeof
(
next_addr
));
&
next_addr
,
sizeof
(
next_addr
));
if
(
this
->
llc_type
==
1
)
{
if
(
this
->
llc_type
==
1
)
{
if
(
this
->
ether_type
==
WL3501_PKT_TYPE_ETHERII
)
{
if
(
this
->
ether_type
==
ARPHRD_ETHER
)
{
if
(
size
>
if
(
size
>
WL3501_BLKSZ
-
sizeof
(
struct
wl3501_rx_hdr
))
{
WL3501_BLKSZ
-
sizeof
(
struct
wl3501_rx_hdr
))
{
wl3501_get_from_wla
(
this
,
this
->
start_seg
+
wl3501_get_from_wla
(
this
,
this
->
start_seg
+
...
@@ -1064,7 +1058,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev,
...
@@ -1064,7 +1058,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev,
wl3501_get_from_wla
(
this
,
addr
,
&
sig
,
sizeof
(
sig
));
wl3501_get_from_wla
(
this
,
addr
,
&
sig
,
sizeof
(
sig
));
if
(
sig
.
status
==
WL3501_STATUS_SUCCESS
)
{
if
(
sig
.
status
==
WL3501_STATUS_SUCCESS
)
{
if
(
this
->
net_type
==
WL3501_NET_TYPE_INFRASTRUCTURE
)
{
if
(
this
->
net_type
==
IW_MODE_INFRA
)
{
if
(
this
->
join_sta_bss
<
this
->
bss_cnt
)
{
if
(
this
->
join_sta_bss
<
this
->
bss_cnt
)
{
i
=
this
->
join_sta_bss
;
i
=
this
->
join_sta_bss
;
memcpy
((
char
*
)
&
(
this
->
bssid
),
memcpy
((
char
*
)
&
(
this
->
bssid
),
...
@@ -1091,7 +1085,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev,
...
@@ -1091,7 +1085,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev,
break
;
break
;
this
->
join_sta_bss
=
j
;
this
->
join_sta_bss
=
j
;
if
(
this
->
join_sta_bss
==
this
->
bss_cnt
)
{
if
(
this
->
join_sta_bss
==
this
->
bss_cnt
)
{
if
(
this
->
net_type
==
WL3501_NET_TYPE_INFRASTRUCTURE
)
if
(
this
->
net_type
==
IW_MODE_INFRA
)
wl3501_mgmt_scan
(
this
,
100
);
wl3501_mgmt_scan
(
this
,
100
);
else
{
else
{
this
->
adhoc_times
++
;
this
->
adhoc_times
++
;
...
@@ -1112,7 +1106,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev,
...
@@ -1112,7 +1106,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev,
static
inline
void
wl3501_alarm_interrupt
(
struct
net_device
*
dev
,
static
inline
void
wl3501_alarm_interrupt
(
struct
net_device
*
dev
,
struct
wl3501_card
*
this
)
struct
wl3501_card
*
this
)
{
{
if
(
this
->
net_type
==
WL3501_NET_TYPE_INFRASTRUCTURE
)
{
if
(
this
->
net_type
==
IW_MODE_INFRA
)
{
printk
(
KERN_INFO
"Wireless LAN offline
\n
"
);
printk
(
KERN_INFO
"Wireless LAN offline
\n
"
);
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
wl3501_mgmt_resync
(
this
);
wl3501_mgmt_resync
(
this
);
...
@@ -1148,13 +1142,13 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
...
@@ -1148,13 +1142,13 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
&
tmp
,
sizeof
(
tmp
));
&
tmp
,
sizeof
(
tmp
));
if
(
tmp
==
0xaaaa
)
{
if
(
tmp
==
0xaaaa
)
{
pkt_len
=
sig
.
size
+
12
-
24
-
4
-
6
;
pkt_len
=
sig
.
size
+
12
-
24
-
4
-
6
;
this
->
ether_type
=
WL3501_PKT_TYPE_ETHERII
;
this
->
ether_type
=
ARPHRD_ETHER
;
}
else
if
(
tmp
==
0xe0e0
)
{
}
else
if
(
tmp
==
0xe0e0
)
{
pkt_len
=
sig
.
size
+
12
-
24
-
4
+
2
;
pkt_len
=
sig
.
size
+
12
-
24
-
4
+
2
;
this
->
ether_type
=
WL3501_PKT_TYPE_ETHER802_3E
;
this
->
ether_type
=
ARPHRD_IEEE80211
;
/* FIXME */
}
else
{
}
else
{
pkt_len
=
sig
.
size
+
12
-
24
-
4
+
2
;
pkt_len
=
sig
.
size
+
12
-
24
-
4
+
2
;
this
->
ether_type
=
WL3501_PKT_TYPE_ETHER802_3F
;
this
->
ether_type
=
ARPHRD_IEEE80211
;
/* FIXME */
}
}
}
else
}
else
pkt_len
=
sig
.
size
-
24
-
4
;
pkt_len
=
sig
.
size
-
24
-
4
;
...
@@ -1466,11 +1460,9 @@ static int wl3501_close(struct net_device *dev)
...
@@ -1466,11 +1460,9 @@ static int wl3501_close(struct net_device *dev)
*/
*/
static
int
wl3501_reset
(
struct
net_device
*
dev
)
static
int
wl3501_reset
(
struct
net_device
*
dev
)
{
{
unsigned
long
flags
;
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
int
rc
=
-
ENODEV
;
int
rc
=
-
ENODEV
;
spin_lock_irqsave
(
&
this
->
lock
,
flags
);
/* Stop processing interrupt from the card */
/* Stop processing interrupt from the card */
wl3501_block_interrupt
(
this
);
wl3501_block_interrupt
(
this
);
...
@@ -1498,7 +1490,6 @@ static int wl3501_reset(struct net_device *dev)
...
@@ -1498,7 +1490,6 @@ static int wl3501_reset(struct net_device *dev)
printk
(
KERN_INFO
"%s: device reset
\n
"
,
dev
->
name
);
printk
(
KERN_INFO
"%s: device reset
\n
"
,
dev
->
name
);
rc
=
0
;
rc
=
0
;
out:
out:
spin_unlock_irqrestore
(
&
this
->
lock
,
flags
);
return
rc
;
return
rc
;
}
}
...
@@ -1683,6 +1674,29 @@ static void wl3501_set_multicast_list(struct net_device *dev)
...
@@ -1683,6 +1674,29 @@ static void wl3501_set_multicast_list(struct net_device *dev)
#endif
#endif
}
}
static
inline
int
wl3501_ethtool_ioctl
(
struct
net_device
*
dev
,
void
*
uaddr
)
{
u32
ethcmd
;
int
rc
=
-
EFAULT
;
if
(
copy_from_user
(
&
ethcmd
,
uaddr
,
sizeof
(
ethcmd
)))
goto
out
;
switch
(
ethcmd
)
{
case
ETHTOOL_GDRVINFO
:
{
struct
ethtool_drvinfo
info
=
{
.
cmd
=
ETHTOOL_GDRVINFO
,
};
strlcpy
(
info
.
driver
,
wl3501_dev_info
,
sizeof
(
info
.
driver
));
rc
=
copy_to_user
(
uaddr
,
&
info
,
sizeof
(
info
))
?
-
EFAULT
:
1
;
}
default:
rc
=
-
EOPNOTSUPP
;
break
;
}
out:
return
rc
;
}
/**
/**
* wl3501_ioctl - Perform IOCTL call functions
* wl3501_ioctl - Perform IOCTL call functions
* @dev - network device
* @dev - network device
...
@@ -1696,27 +1710,33 @@ static void wl3501_set_multicast_list(struct net_device *dev)
...
@@ -1696,27 +1710,33 @@ static void wl3501_set_multicast_list(struct net_device *dev)
*
*
* CAUTION: To prevent interrupted by wl3501_interrupt() and timer-based
* CAUTION: To prevent interrupted by wl3501_interrupt() and timer-based
* wl3501_hard_start_xmit() from other interrupts, this should be run
* wl3501_hard_start_xmit() from other interrupts, this should be run
* single-threaded. This function is expected to be a rare operation, and it's
* single-threaded.
* simpler to just use cli() to disable ALL interrupts.
*/
*/
static
int
wl3501_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
)
static
int
wl3501_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
rq
,
int
cmd
)
{
{
int
rc
=
-
ENODEV
;
int
rc
=
-
ENODEV
;
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
struct
wl3501_ioctl_parm
parm
;
struct
wl3501_ioctl_blk
*
blk
=
(
struct
wl3501_ioctl_blk
*
)
&
rq
->
ifr_data
;
if
(
!
netif_device_present
(
dev
))
if
(
!
netif_device_present
(
dev
))
goto
out
;
goto
out
;
switch
(
blk
->
cmd
)
{
switch
(
cmd
)
{
case
WL3501_IOCTL_CMD_SET_RESET
:
/* Reset drv - needed after set */
case
SIOCETHTOOL
:
rc
=
wl3501_ethtool_ioctl
(
dev
,
(
void
*
)
rq
->
ifr_data
);
break
;
#if 0
/* FIXME: has to go to the private stuff in iw_handler_def */
/*
* Private IOCTLs
*/
case WL3501_IOCTL_CMD_SET_RESET:
rc = -EPERM;
rc = -EPERM;
if (!capable(CAP_NET_ADMIN))
if (!capable(CAP_NET_ADMIN))
break;
break;
spin_lock_irqsave(&this->lock, flags);
rc = wl3501_reset(dev);
rc = wl3501_reset(dev);
spin_unlock_irqrestore(&this->lock, flags);
break;
break;
case
WL3501_IOCTL_CMD_WRITE_FLASH
:
{
/* Write firmware into Flash */
case WL3501_IOCTL_CMD_WRITE_FLASH: {
unsigned char bf[1028];
unsigned char bf[1028];
rc = -EPERM;
rc = -EPERM;
...
@@ -1728,10 +1748,13 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
...
@@ -1728,10 +1748,13 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
rc = -EFAULT;
rc = -EFAULT;
if (copy_from_user(bf, blk->data, blk->len))
if (copy_from_user(bf, blk->data, blk->len))
break;
break;
spin_lock_irqsave(&this->lock, flags);
rc = wl3501_write_flash(this, bf, blk->len);
rc = wl3501_write_flash(this, bf, blk->len);
spin_unlock_irqrestore(&this->lock, flags);
}
}
break;
break;
case WL3501_IOCTL_CMD_GET_PARAMETER:
case WL3501_IOCTL_CMD_GET_PARAMETER:
spin_lock_irqsave(&this->lock, flags);
parm.def_chan = this->def_chan;
parm.def_chan = this->def_chan;
parm.chan = this->chan;
parm.chan = this->chan;
parm.net_type = this->net_type;
parm.net_type = this->net_type;
...
@@ -1741,6 +1764,7 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
...
@@ -1741,6 +1764,7 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
memcpy((char *)&(parm.keep_essid[0]),
memcpy((char *)&(parm.keep_essid[0]),
(char *)&(this->keep_essid[0]), 34);
(char *)&(this->keep_essid[0]), 34);
memcpy((char *)&(parm.essid[0]), (char *)&(this->essid[0]), 34);
memcpy((char *)&(parm.essid[0]), (char *)&(this->essid[0]), 34);
spin_unlock_irqrestore(&this->lock, flags);
blk->len = sizeof(parm);
blk->len = sizeof(parm);
rc = -EFAULT;
rc = -EFAULT;
if (copy_to_user(blk->data, &parm, blk->len))
if (copy_to_user(blk->data, &parm, blk->len))
...
@@ -1754,11 +1778,14 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
...
@@ -1754,11 +1778,14 @@ static int wl3501_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
rc = -EFAULT;
rc = -EFAULT;
if (copy_from_user(&parm, blk->data, sizeof(parm)))
if (copy_from_user(&parm, blk->data, sizeof(parm)))
break;
break;
spin_lock_irqsave(&this->lock, flags);
this->def_chan = parm.def_chan;
this->def_chan = parm.def_chan;
this->net_type = parm.net_type;
this->net_type = parm.net_type;
memcpy((char *)&(this->essid[0]), (char *)&(parm.essid[0]), 34);
memcpy((char *)&(this->essid[0]), (char *)&(parm.essid[0]), 34);
rc = wl3501_reset(dev);
rc = wl3501_reset(dev);
spin_unlock_irqrestore(&this->lock, flags);
break;
break;
#endif
default:
default:
rc
=
-
EOPNOTSUPP
;
rc
=
-
EOPNOTSUPP
;
}
}
...
@@ -1828,6 +1855,130 @@ static void wl3501_flush_stale_links(void)
...
@@ -1828,6 +1855,130 @@ static void wl3501_flush_stale_links(void)
}
}
}
}
static
int
wl3501_get_name
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
strlcpy
(
wrqu
->
name
,
"IEEE 802.11-FH"
,
sizeof
(
wrqu
->
name
));
return
0
;
}
static
int
wl3501_set_mode
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
unsigned
long
flags
;
int
rc
;
spin_lock_irqsave
(
&
this
->
lock
,
flags
);
if
(
wrqu
->
mode
==
IW_MODE_INFRA
||
wrqu
->
mode
==
IW_MODE_ADHOC
||
wrqu
->
mode
==
IW_MODE_AUTO
)
{
this
->
net_type
=
wrqu
->
mode
;
rc
=
wl3501_mgmt_start
(
this
);
}
else
rc
=
-
EINVAL
;
spin_unlock_irqrestore
(
&
this
->
lock
,
flags
);
return
rc
;
}
static
int
wl3501_get_mode
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
wrqu
->
mode
=
this
->
net_type
;
return
0
;
}
static
int
wl3501_get_range
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
iw_range
*
range
=
(
struct
iw_range
*
)
extra
;
/* Set the length (very important for backward compatibility) */
wrqu
->
data
.
length
=
sizeof
(
*
range
);
/* Set all the info we don't care or don't know about to zero */
memset
(
range
,
0
,
sizeof
(
*
range
));
/* Set the Wireless Extension versions */
range
->
we_version_compiled
=
WIRELESS_EXT
;
range
->
we_version_source
=
1
;
range
->
throughput
=
2
*
1000
*
1000
;
/* ~2 Mb/s */
/* FIXME: study the code to fill in more fields... */
return
0
;
}
static
int
wl3501_get_wap
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
wrqu
->
ap_addr
.
sa_family
=
this
->
ether_type
;
memcpy
(
wrqu
->
ap_addr
.
sa_data
,
&
this
->
bssid
,
ETH_ALEN
);
return
0
;
}
static
int
wl3501_set_essid
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
this
->
lock
,
flags
);
if
(
wrqu
->
data
.
flags
)
strlcpy
(
this
->
essid
,
extra
,
min_t
(
u16
,
wrqu
->
data
.
length
,
IW_ESSID_MAX_SIZE
));
spin_unlock_irqrestore
(
&
this
->
lock
,
flags
);
return
0
;
}
static
int
wl3501_get_essid
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
{
struct
wl3501_card
*
this
=
(
struct
wl3501_card
*
)
dev
->
priv
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
this
->
lock
,
flags
);
wrqu
->
essid
.
flags
=
1
;
wrqu
->
essid
.
length
=
IW_ESSID_MAX_SIZE
;
strlcpy
(
extra
,
this
->
essid
,
IW_ESSID_MAX_SIZE
);
spin_unlock_irqrestore
(
&
this
->
lock
,
flags
);
return
0
;
}
static
const
iw_handler
wl3501_handler
[]
=
{
[
SIOCGIWNAME
-
SIOCSIWCOMMIT
]
=
wl3501_get_name
,
//[SIOCSIWNWID - SIOCSIWCOMMIT] = wl3501_set_nwid,
//[SIOCGIWNWID - SIOCSIWCOMMIT] = wl3501_get_nwid,
//[SIOCSIWFREQ - SIOCSIWCOMMIT] = wl3501_set_freq,
//[SIOCGIWFREQ - SIOCSIWCOMMIT] = wl3501_get_freq,
[
SIOCSIWMODE
-
SIOCSIWCOMMIT
]
=
wl3501_set_mode
,
[
SIOCGIWMODE
-
SIOCSIWCOMMIT
]
=
wl3501_get_mode
,
//[SIOCSIWSENS - SIOCSIWCOMMIT] = wl3501_set_sens,
//[SIOCGIWSENS - SIOCSIWCOMMIT] = wl3501_get_sens,
[
SIOCGIWRANGE
-
SIOCSIWCOMMIT
]
=
wl3501_get_range
,
//[SIOCSIWSPY - SIOCSIWCOMMIT] = iw_handler_set_spy,
//[SIOCGIWSPY - SIOCSIWCOMMIT] = iw_handler_get_spy,
[
SIOCSIWTHRSPY
-
SIOCSIWCOMMIT
]
=
iw_handler_set_thrspy
,
[
SIOCGIWTHRSPY
-
SIOCSIWCOMMIT
]
=
iw_handler_get_thrspy
,
//[SIOCSIWAP - SIOCSIWCOMMIT] = wl3501_set_wap,
[
SIOCGIWAP
-
SIOCSIWCOMMIT
]
=
wl3501_get_wap
,
[
SIOCSIWESSID
-
SIOCSIWCOMMIT
]
=
wl3501_set_essid
,
[
SIOCGIWESSID
-
SIOCSIWCOMMIT
]
=
wl3501_get_essid
,
//[SIOCSIWENCODE - SIOCSIWCOMMIT] = wl3501_set_encode,
//[SIOCGIWENCODE - SIOCSIWCOMMIT] = wl3501_get_encode,
};
static
const
struct
iw_handler_def
wl3501_handler_def
=
{
.
num_standard
=
sizeof
(
wl3501_handler
)
/
sizeof
(
iw_handler
),
.
standard
=
(
iw_handler
*
)
wl3501_handler
,
.
spy_offset
=
offsetof
(
struct
wl3501_card
,
spy_data
),
};
/**
/**
* wl3501_attach - creates an "instance" of the driver
* wl3501_attach - creates an "instance" of the driver
*
*
...
@@ -1894,6 +2045,7 @@ static dev_link_t *wl3501_attach(void)
...
@@ -1894,6 +2045,7 @@ static dev_link_t *wl3501_attach(void)
dev
->
get_wireless_stats
=
wl3501_get_wireless_stats
;
dev
->
get_wireless_stats
=
wl3501_get_wireless_stats
;
dev
->
set_multicast_list
=
wl3501_set_multicast_list
;
dev
->
set_multicast_list
=
wl3501_set_multicast_list
;
dev
->
do_ioctl
=
wl3501_ioctl
;
dev
->
do_ioctl
=
wl3501_ioctl
;
dev
->
wireless_handlers
=
(
struct
iw_handler_def
*
)
&
wl3501_handler_def
;
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
link
->
priv
=
link
->
irq
.
Instance
=
dev
;
link
->
priv
=
link
->
irq
.
Instance
=
dev
;
...
@@ -2021,8 +2173,8 @@ static void wl3501_config(dev_link_t *link)
...
@@ -2021,8 +2173,8 @@ static void wl3501_config(dev_link_t *link)
printk
(
"%c%02x"
,
i
?
':'
:
' '
,
dev
->
dev_addr
[
i
]);
printk
(
"%c%02x"
,
i
?
':'
:
' '
,
dev
->
dev_addr
[
i
]);
}
}
printk
(
"
\n
"
);
printk
(
"
\n
"
);
/* initialize card parameter - add by jss */
/* initialize card parameter - add
ed
by jss */
this
->
net_type
=
WL3501_NET_TYPE_INFRASTRUCTURE
;
this
->
net_type
=
IW_MODE_INFRA
;
this
->
llc_type
=
1
;
this
->
llc_type
=
1
;
this
->
def_chan
=
1
;
this
->
def_chan
=
1
;
this
->
bss_cnt
=
0
;
this
->
bss_cnt
=
0
;
...
@@ -2071,7 +2223,7 @@ static void wl3501_config(dev_link_t *link)
...
@@ -2071,7 +2223,7 @@ static void wl3501_config(dev_link_t *link)
*/
*/
static
void
wl3501_release
(
unsigned
long
arg
)
static
void
wl3501_release
(
unsigned
long
arg
)
{
{
dev_link_t
*
link
=
(
dev_link_t
*
)
arg
;
dev_link_t
*
link
=
(
dev_link_t
*
)
arg
;
struct
net_device
*
dev
=
link
->
priv
;
struct
net_device
*
dev
=
link
->
priv
;
/* If the device is currently in use, we won't release until it is
/* If the device is currently in use, we won't release until it is
...
@@ -2199,3 +2351,11 @@ static void __exit wl3501_exit_module(void)
...
@@ -2199,3 +2351,11 @@ static void __exit wl3501_exit_module(void)
module_init
(
wl3501_init_module
);
module_init
(
wl3501_init_module
);
module_exit
(
wl3501_exit_module
);
module_exit
(
wl3501_exit_module
);
MODULE_PARM
(
wl3501_irq_mask
,
"i"
);
MODULE_PARM
(
wl3501_irq_list
,
"1-4i"
);
MODULE_AUTHOR
(
"Fox Chen <mhchen@golf.ccl.itri.org.tw>, "
"Arnaldo Carvalho de Melo <acme@conectiva.com.br>,"
"Gustavo Niemeyer <niemeyer@conectiva.com>"
);
MODULE_DESCRIPTION
(
"Planet wl3501 wireless driver"
);
MODULE_LICENSE
(
"GPL"
);
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