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
5928b91a
Commit
5928b91a
authored
Dec 16, 2010
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'wl12xx-next' of
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
parents
7d5f01ad
248daa08
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
848 additions
and
324 deletions
+848
-324
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/Kconfig
+10
-0
drivers/net/wireless/wl12xx/Makefile
drivers/net/wireless/wl12xx/Makefile
+3
-0
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+2
-2
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+7
-2
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+16
-1
drivers/net/wireless/wl12xx/boot.h
drivers/net/wireless/wl12xx/boot.h
+1
-0
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+69
-0
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+4
-0
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+41
-151
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+9
-4
drivers/net/wireless/wl12xx/io.c
drivers/net/wireless/wl12xx/io.c
+1
-0
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+84
-35
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.c
+4
-0
drivers/net/wireless/wl12xx/sdio_test.c
drivers/net/wireless/wl12xx/sdio_test.c
+520
-0
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+49
-11
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+16
-113
drivers/net/wireless/wl12xx/wl12xx_80211.h
drivers/net/wireless/wl12xx/wl12xx_80211.h
+12
-5
No files found.
drivers/net/wireless/wl12xx/Kconfig
View file @
5928b91a
...
...
@@ -52,6 +52,16 @@ config WL12XX_SDIO
If you choose to build a module, it'll be called wl12xx_sdio.
Say N if unsure.
config WL12XX_SDIO_TEST
tristate "TI wl12xx SDIO testing support"
depends on WL12XX && MMC
default n
---help---
This module adds support for the SDIO bus testing with the
TI wl12xx chipsets. You probably don't want this unless you are
testing a new hardware platform. Select this if you want to test the
SDIO bus which is connected to the wl12xx chip.
config WL12XX_PLATFORM_DATA
bool
depends on WL12XX_SDIO != n || WL1251_SDIO != n
...
...
drivers/net/wireless/wl12xx/Makefile
View file @
5928b91a
...
...
@@ -3,11 +3,14 @@ wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
wl12xx_spi-objs
=
spi.o
wl12xx_sdio-objs
=
sdio.o
wl12xx_sdio_test-objs
=
sdio_test.o
wl12xx-$(CONFIG_NL80211_TESTMODE)
+=
testmode.o
obj-$(CONFIG_WL12XX)
+=
wl12xx.o
obj-$(CONFIG_WL12XX_SPI)
+=
wl12xx_spi.o
obj-$(CONFIG_WL12XX_SDIO)
+=
wl12xx_sdio.o
obj-$(CONFIG_WL12XX_SDIO_TEST)
+=
wl12xx_sdio_test.o
# small builtin driver bit
obj-$(CONFIG_WL12XX_PLATFORM_DATA)
+=
wl12xx_platform_data.o
drivers/net/wireless/wl12xx/acx.c
View file @
5928b91a
...
...
@@ -1041,7 +1041,7 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
return
ret
;
}
int
wl1271_acx_arp_ip_filter
(
struct
wl1271
*
wl
,
bool
enable
,
__be32
address
)
int
wl1271_acx_arp_ip_filter
(
struct
wl1271
*
wl
,
u8
enable
,
__be32
address
)
{
struct
wl1271_acx_arp_filter
*
acx
;
int
ret
;
...
...
@@ -1057,7 +1057,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, __be32 address)
acx
->
version
=
ACX_IPV4_VERSION
;
acx
->
enable
=
enable
;
if
(
enable
==
true
)
if
(
enable
)
memcpy
(
acx
->
address
,
&
address
,
ACX_IPV4_ADDR_SIZE
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_ARP_IP_FILTER
,
...
...
drivers/net/wireless/wl12xx/acx.h
View file @
5928b91a
...
...
@@ -868,10 +868,15 @@ struct wl1271_acx_bet_enable {
#define ACX_IPV4_VERSION 4
#define ACX_IPV6_VERSION 6
#define ACX_IPV4_ADDR_SIZE 4
/* bitmap of enabled arp_filter features */
#define ACX_ARP_FILTER_ARP_FILTERING BIT(0)
#define ACX_ARP_FILTER_AUTO_ARP BIT(1)
struct
wl1271_acx_arp_filter
{
struct
acx_header
header
;
u8
version
;
/* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
u8
enable
;
/*
1 to enable ARP filtering, 0 to disable
*/
u8
enable
;
/*
bitmap of enabled ARP filtering features
*/
u8
padding
[
2
];
u8
address
[
16
];
/* The configured device IP address - all ARP
requests directed to this IP address will pass
...
...
@@ -1168,7 +1173,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl);
int
wl1271_acx_init_rx_interrupt
(
struct
wl1271
*
wl
);
int
wl1271_acx_smart_reflex
(
struct
wl1271
*
wl
);
int
wl1271_acx_bet_enable
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_arp_ip_filter
(
struct
wl1271
*
wl
,
bool
enable
,
__be32
address
);
int
wl1271_acx_arp_ip_filter
(
struct
wl1271
*
wl
,
u8
enable
,
__be32
address
);
int
wl1271_acx_pm_config
(
struct
wl1271
*
wl
);
int
wl1271_acx_keep_alive_mode
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_keep_alive_config
(
struct
wl1271
*
wl
,
u8
index
,
u8
tpl_valid
);
...
...
drivers/net/wireless/wl12xx/boot.c
View file @
5928b91a
...
...
@@ -467,7 +467,8 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
wl
->
hw_pg_ver
=
(
s8
)
fuse
;
}
int
wl1271_boot
(
struct
wl1271
*
wl
)
/* uploads NVS and firmware */
int
wl1271_load_firmware
(
struct
wl1271
*
wl
)
{
int
ret
=
0
;
u32
tmp
,
clk
,
pause
;
...
...
@@ -572,6 +573,20 @@ int wl1271_boot(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out
;
out:
return
ret
;
}
EXPORT_SYMBOL_GPL
(
wl1271_load_firmware
);
int
wl1271_boot
(
struct
wl1271
*
wl
)
{
int
ret
;
/* upload NVS and firmware */
ret
=
wl1271_load_firmware
(
wl
);
if
(
ret
)
return
ret
;
/* 10.5 start firmware */
ret
=
wl1271_boot_run_firmware
(
wl
);
if
(
ret
<
0
)
...
...
drivers/net/wireless/wl12xx/boot.h
View file @
5928b91a
...
...
@@ -27,6 +27,7 @@
#include "wl12xx.h"
int
wl1271_boot
(
struct
wl1271
*
wl
);
int
wl1271_load_firmware
(
struct
wl1271
*
wl
);
#define WL1271_NO_SUBBANDS 8
#define WL1271_NO_POWER_LEVELS 4
...
...
drivers/net/wireless/wl12xx/cmd.c
View file @
5928b91a
...
...
@@ -611,6 +611,75 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
return
ret
;
}
struct
sk_buff
*
wl1271_cmd_build_ap_probe_req
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
int
ret
;
if
(
!
skb
)
skb
=
ieee80211_ap_probereq_get
(
wl
->
hw
,
wl
->
vif
);
if
(
!
skb
)
goto
out
;
wl1271_dump
(
DEBUG_SCAN
,
"AP PROBE REQ: "
,
skb
->
data
,
skb
->
len
);
if
(
wl
->
band
==
IEEE80211_BAND_2GHZ
)
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
skb
->
data
,
skb
->
len
,
0
,
wl
->
conf
.
tx
.
basic_rate
);
else
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
skb
->
data
,
skb
->
len
,
0
,
wl
->
conf
.
tx
.
basic_rate_5
);
if
(
ret
<
0
)
wl1271_error
(
"Unable to set ap probe request template."
);
out:
return
skb
;
}
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
__be32
ip_addr
)
{
int
ret
;
struct
wl12xx_arp_rsp_template
tmpl
;
struct
ieee80211_hdr_3addr
*
hdr
;
struct
arphdr
*
arp_hdr
;
memset
(
&
tmpl
,
0
,
sizeof
(
tmpl
));
/* mac80211 header */
hdr
=
&
tmpl
.
hdr
;
hdr
->
frame_control
=
cpu_to_le16
(
IEEE80211_FTYPE_DATA
|
IEEE80211_STYPE_DATA
|
IEEE80211_FCTL_TODS
);
memcpy
(
hdr
->
addr1
,
wl
->
vif
->
bss_conf
.
bssid
,
ETH_ALEN
);
memcpy
(
hdr
->
addr2
,
wl
->
vif
->
addr
,
ETH_ALEN
);
memset
(
hdr
->
addr3
,
0xff
,
ETH_ALEN
);
/* llc layer */
memcpy
(
tmpl
.
llc_hdr
,
rfc1042_header
,
sizeof
(
rfc1042_header
));
tmpl
.
llc_type
=
htons
(
ETH_P_ARP
);
/* arp header */
arp_hdr
=
&
tmpl
.
arp_hdr
;
arp_hdr
->
ar_hrd
=
htons
(
ARPHRD_ETHER
);
arp_hdr
->
ar_pro
=
htons
(
ETH_P_IP
);
arp_hdr
->
ar_hln
=
ETH_ALEN
;
arp_hdr
->
ar_pln
=
4
;
arp_hdr
->
ar_op
=
htons
(
ARPOP_REPLY
);
/* arp payload */
memcpy
(
tmpl
.
sender_hw
,
wl
->
vif
->
addr
,
ETH_ALEN
);
tmpl
.
sender_ip
=
ip_addr
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_ARP_RSP
,
&
tmpl
,
sizeof
(
tmpl
),
0
,
wl
->
basic_rate
);
return
ret
;
}
int
wl1271_build_qos_null_data
(
struct
wl1271
*
wl
)
{
struct
ieee80211_qos_hdr
template
;
...
...
drivers/net/wireless/wl12xx/cmd.h
View file @
5928b91a
...
...
@@ -49,6 +49,9 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
int
wl1271_cmd_build_probe_req
(
struct
wl1271
*
wl
,
const
u8
*
ssid
,
size_t
ssid_len
,
const
u8
*
ie
,
size_t
ie_len
,
u8
band
);
struct
sk_buff
*
wl1271_cmd_build_ap_probe_req
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
);
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
__be32
ip_addr
);
int
wl1271_build_qos_null_data
(
struct
wl1271
*
wl
);
int
wl1271_cmd_build_klv_null_data
(
struct
wl1271
*
wl
);
int
wl1271_cmd_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
...
...
@@ -122,6 +125,7 @@ enum cmd_templ {
CMD_TEMPL_CTS
,
/*
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
CMD_TEMPL_ARP_RSP
,
CMD_TEMPL_MAX
=
0xff
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
View file @
5928b91a
...
...
@@ -66,19 +66,10 @@ static const struct file_operations name## _ops = { \
};
#define DEBUGFS_ADD(name, parent) \
wl->debugfs.name = debugfs_create_file(#name, 0400, parent,
\
entry = debugfs_create_file(#name, 0400, parent,
\
wl, &name## _ops); \
if (IS_ERR(wl->debugfs.name)) { \
ret = PTR_ERR(wl->debugfs.name); \
wl->debugfs.name = NULL; \
goto out; \
}
#define DEBUGFS_DEL(name) \
do { \
debugfs_remove(wl->debugfs.name); \
wl->debugfs.name = NULL; \
} while (0)
if (!entry || IS_ERR(entry)) \
goto err; \
#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \
static ssize_t sub## _ ##name## _read(struct file *file, \
...
...
@@ -100,10 +91,7 @@ static const struct file_operations sub## _ ##name## _ops = { \
};
#define DEBUGFS_FWSTATS_ADD(sub, name) \
DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
#define DEBUGFS_FWSTATS_DEL(sub, name) \
DEBUGFS_DEL(sub## _ ##name)
DEBUGFS_ADD(sub## _ ##name, stats)
static
void
wl1271_debugfs_update_stats
(
struct
wl1271
*
wl
)
{
...
...
@@ -237,7 +225,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
char
buf
[
20
];
int
res
;
queue_len
=
skb_queue_len
(
&
wl
->
tx_queue
)
;
queue_len
=
wl
->
tx_queue_count
;
res
=
scnprintf
(
buf
,
sizeof
(
buf
),
"%u
\n
"
,
queue_len
);
return
simple_read_from_buffer
(
userbuf
,
count
,
ppos
,
buf
,
res
);
...
...
@@ -305,109 +293,16 @@ static const struct file_operations gpio_power_ops = {
.
llseek
=
default_llseek
,
};
static
void
wl1271_debugfs_delete_files
(
struct
wl1271
*
wl
)
{
DEBUGFS_FWSTATS_DEL
(
tx
,
internal_desc_overflow
);
DEBUGFS_FWSTATS_DEL
(
rx
,
out_of_mem
);
DEBUGFS_FWSTATS_DEL
(
rx
,
hdr_overflow
);
DEBUGFS_FWSTATS_DEL
(
rx
,
hw_stuck
);
DEBUGFS_FWSTATS_DEL
(
rx
,
dropped
);
DEBUGFS_FWSTATS_DEL
(
rx
,
fcs_err
);
DEBUGFS_FWSTATS_DEL
(
rx
,
xfr_hint_trig
);
DEBUGFS_FWSTATS_DEL
(
rx
,
path_reset
);
DEBUGFS_FWSTATS_DEL
(
rx
,
reset_counter
);
DEBUGFS_FWSTATS_DEL
(
dma
,
rx_requested
);
DEBUGFS_FWSTATS_DEL
(
dma
,
rx_errors
);
DEBUGFS_FWSTATS_DEL
(
dma
,
tx_requested
);
DEBUGFS_FWSTATS_DEL
(
dma
,
tx_errors
);
DEBUGFS_FWSTATS_DEL
(
isr
,
cmd_cmplt
);
DEBUGFS_FWSTATS_DEL
(
isr
,
fiqs
);
DEBUGFS_FWSTATS_DEL
(
isr
,
rx_headers
);
DEBUGFS_FWSTATS_DEL
(
isr
,
rx_mem_overflow
);
DEBUGFS_FWSTATS_DEL
(
isr
,
rx_rdys
);
DEBUGFS_FWSTATS_DEL
(
isr
,
irqs
);
DEBUGFS_FWSTATS_DEL
(
isr
,
tx_procs
);
DEBUGFS_FWSTATS_DEL
(
isr
,
decrypt_done
);
DEBUGFS_FWSTATS_DEL
(
isr
,
dma0_done
);
DEBUGFS_FWSTATS_DEL
(
isr
,
dma1_done
);
DEBUGFS_FWSTATS_DEL
(
isr
,
tx_exch_complete
);
DEBUGFS_FWSTATS_DEL
(
isr
,
commands
);
DEBUGFS_FWSTATS_DEL
(
isr
,
rx_procs
);
DEBUGFS_FWSTATS_DEL
(
isr
,
hw_pm_mode_changes
);
DEBUGFS_FWSTATS_DEL
(
isr
,
host_acknowledges
);
DEBUGFS_FWSTATS_DEL
(
isr
,
pci_pm
);
DEBUGFS_FWSTATS_DEL
(
isr
,
wakeups
);
DEBUGFS_FWSTATS_DEL
(
isr
,
low_rssi
);
DEBUGFS_FWSTATS_DEL
(
wep
,
addr_key_count
);
DEBUGFS_FWSTATS_DEL
(
wep
,
default_key_count
);
/* skipping wep.reserved */
DEBUGFS_FWSTATS_DEL
(
wep
,
key_not_found
);
DEBUGFS_FWSTATS_DEL
(
wep
,
decrypt_fail
);
DEBUGFS_FWSTATS_DEL
(
wep
,
packets
);
DEBUGFS_FWSTATS_DEL
(
wep
,
interrupt
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
ps_enter
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
elp_enter
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
missing_bcns
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
wake_on_host
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
wake_on_timer_exp
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
tx_with_ps
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
tx_without_ps
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
rcvd_beacons
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
power_save_off
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
enable_ps
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
disable_ps
);
DEBUGFS_FWSTATS_DEL
(
pwr
,
fix_tsf_ps
);
/* skipping cont_miss_bcns_spread for now */
DEBUGFS_FWSTATS_DEL
(
pwr
,
rcvd_awake_beacons
);
DEBUGFS_FWSTATS_DEL
(
mic
,
rx_pkts
);
DEBUGFS_FWSTATS_DEL
(
mic
,
calc_failure
);
DEBUGFS_FWSTATS_DEL
(
aes
,
encrypt_fail
);
DEBUGFS_FWSTATS_DEL
(
aes
,
decrypt_fail
);
DEBUGFS_FWSTATS_DEL
(
aes
,
encrypt_packets
);
DEBUGFS_FWSTATS_DEL
(
aes
,
decrypt_packets
);
DEBUGFS_FWSTATS_DEL
(
aes
,
encrypt_interrupt
);
DEBUGFS_FWSTATS_DEL
(
aes
,
decrypt_interrupt
);
DEBUGFS_FWSTATS_DEL
(
event
,
heart_beat
);
DEBUGFS_FWSTATS_DEL
(
event
,
calibration
);
DEBUGFS_FWSTATS_DEL
(
event
,
rx_mismatch
);
DEBUGFS_FWSTATS_DEL
(
event
,
rx_mem_empty
);
DEBUGFS_FWSTATS_DEL
(
event
,
rx_pool
);
DEBUGFS_FWSTATS_DEL
(
event
,
oom_late
);
DEBUGFS_FWSTATS_DEL
(
event
,
phy_transmit_error
);
DEBUGFS_FWSTATS_DEL
(
event
,
tx_stuck
);
DEBUGFS_FWSTATS_DEL
(
ps
,
pspoll_timeouts
);
DEBUGFS_FWSTATS_DEL
(
ps
,
upsd_timeouts
);
DEBUGFS_FWSTATS_DEL
(
ps
,
upsd_max_sptime
);
DEBUGFS_FWSTATS_DEL
(
ps
,
upsd_max_apturn
);
DEBUGFS_FWSTATS_DEL
(
ps
,
pspoll_max_apturn
);
DEBUGFS_FWSTATS_DEL
(
ps
,
pspoll_utilization
);
DEBUGFS_FWSTATS_DEL
(
ps
,
upsd_utilization
);
DEBUGFS_FWSTATS_DEL
(
rxpipe
,
rx_prep_beacon_drop
);
DEBUGFS_FWSTATS_DEL
(
rxpipe
,
descr_host_int_trig_rx_data
);
DEBUGFS_FWSTATS_DEL
(
rxpipe
,
beacon_buffer_thres_host_int_trig_rx_data
);
DEBUGFS_FWSTATS_DEL
(
rxpipe
,
missed_beacon_host_int_trig_rx_data
);
DEBUGFS_FWSTATS_DEL
(
rxpipe
,
tx_xfr_host_int_trig_rx_data
);
DEBUGFS_DEL
(
tx_queue_len
);
DEBUGFS_DEL
(
retry_count
);
DEBUGFS_DEL
(
excessive_retries
);
DEBUGFS_DEL
(
gpio_power
);
}
static
int
wl1271_debugfs_add_files
(
struct
wl1271
*
wl
)
{
int
ret
=
0
;
struct
dentry
*
entry
,
*
stats
;
stats
=
debugfs_create_dir
(
"fw-statistics"
,
wl
->
rootdir
);
if
(
!
stats
||
IS_ERR
(
stats
))
{
entry
=
stats
;
goto
err
;
}
DEBUGFS_FWSTATS_ADD
(
tx
,
internal_desc_overflow
);
...
...
@@ -500,21 +395,33 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl)
DEBUGFS_FWSTATS_ADD
(
rxpipe
,
missed_beacon_host_int_trig_rx_data
);
DEBUGFS_FWSTATS_ADD
(
rxpipe
,
tx_xfr_host_int_trig_rx_data
);
DEBUGFS_ADD
(
tx_queue_len
,
wl
->
debugfs
.
rootdir
);
DEBUGFS_ADD
(
retry_count
,
wl
->
debugfs
.
rootdir
);
DEBUGFS_ADD
(
excessive_retries
,
wl
->
debugfs
.
rootdir
);
DEBUGFS_ADD
(
tx_queue_len
,
wl
->
rootdir
);
DEBUGFS_ADD
(
retry_count
,
wl
->
rootdir
);
DEBUGFS_ADD
(
excessive_retries
,
wl
->
rootdir
);
DEBUGFS_ADD
(
gpio_power
,
wl
->
debugfs
.
rootdir
);
DEBUGFS_ADD
(
gpio_power
,
wl
->
rootdir
);
out:
if
(
ret
<
0
)
wl1271_debugfs_delete_files
(
wl
);
entry
=
debugfs_create_x32
(
"debug_level"
,
0600
,
wl
->
rootdir
,
&
wl12xx_debug_level
);
if
(
!
entry
||
IS_ERR
(
entry
))
goto
err
;
return
0
;
err:
if
(
IS_ERR
(
entry
))
ret
=
PTR_ERR
(
entry
);
else
ret
=
-
ENOMEM
;
return
ret
;
}
void
wl1271_debugfs_reset
(
struct
wl1271
*
wl
)
{
if
(
!
wl
->
rootdir
)
return
;
memset
(
wl
->
stats
.
fw_stats
,
0
,
sizeof
(
*
wl
->
stats
.
fw_stats
));
wl
->
stats
.
retry_count
=
0
;
wl
->
stats
.
excessive_retries
=
0
;
...
...
@@ -524,23 +431,15 @@ int wl1271_debugfs_init(struct wl1271 *wl)
{
int
ret
;
wl
->
debugfs
.
rootdir
=
debugfs_create_dir
(
KBUILD_MODNAME
,
NULL
);
wl
->
rootdir
=
debugfs_create_dir
(
KBUILD_MODNAME
,
wl
->
hw
->
wiphy
->
debugfsdir
);
if
(
IS_ERR
(
wl
->
debugfs
.
rootdir
))
{
ret
=
PTR_ERR
(
wl
->
debugfs
.
rootdir
);
wl
->
debugfs
.
rootdir
=
NULL
;
if
(
IS_ERR
(
wl
->
rootdir
))
{
ret
=
PTR_ERR
(
wl
->
rootdir
);
wl
->
rootdir
=
NULL
;
goto
err
;
}
wl
->
debugfs
.
fw_statistics
=
debugfs_create_dir
(
"fw-statistics"
,
wl
->
debugfs
.
rootdir
);
if
(
IS_ERR
(
wl
->
debugfs
.
fw_statistics
))
{
ret
=
PTR_ERR
(
wl
->
debugfs
.
fw_statistics
);
wl
->
debugfs
.
fw_statistics
=
NULL
;
goto
err_root
;
}
wl
->
stats
.
fw_stats
=
kzalloc
(
sizeof
(
*
wl
->
stats
.
fw_stats
),
GFP_KERNEL
);
...
...
@@ -563,12 +462,8 @@ int wl1271_debugfs_init(struct wl1271 *wl)
wl
->
stats
.
fw_stats
=
NULL
;
err_fw:
debugfs_remove
(
wl
->
debugfs
.
fw_statistics
);
wl
->
debugfs
.
fw_statistics
=
NULL
;
err_root:
debugfs_remove
(
wl
->
debugfs
.
rootdir
);
wl
->
debugfs
.
rootdir
=
NULL
;
debugfs_remove_recursive
(
wl
->
rootdir
);
wl
->
rootdir
=
NULL
;
err:
return
ret
;
...
...
@@ -576,15 +471,10 @@ int wl1271_debugfs_init(struct wl1271 *wl)
void
wl1271_debugfs_exit
(
struct
wl1271
*
wl
)
{
wl1271_debugfs_delete_files
(
wl
);
kfree
(
wl
->
stats
.
fw_stats
);
wl
->
stats
.
fw_stats
=
NULL
;
debugfs_remove
(
wl
->
debugfs
.
fw_statistics
);
wl
->
debugfs
.
fw_statistics
=
NULL
;
debugfs_remove
(
wl
->
debugfs
.
rootdir
);
wl
->
debugfs
.
rootdir
=
NULL
;
debugfs_remove_recursive
(
wl
->
rootdir
);
wl
->
rootdir
=
NULL
;
}
drivers/net/wireless/wl12xx/init.c
View file @
5928b91a
...
...
@@ -53,18 +53,16 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl)
int
wl1271_init_templates_config
(
struct
wl1271
*
wl
)
{
int
ret
,
i
;
size_t
size
;
/* send empty templates for fw memory reservation */
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
NULL
,
sizeof
(
struct
wl12xx_probe_req_template
)
,
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
size
=
sizeof
(
struct
wl12xx_probe_req_template
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
NULL
,
size
,
0
,
NULL
,
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -102,6 +100,13 @@ int wl1271_init_templates_config(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_ARP_RSP
,
NULL
,
sizeof
(
struct
wl12xx_arp_rsp_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
for
(
i
=
0
;
i
<
CMD_TEMPL_KLV_IDX_MAX
;
i
++
)
{
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_KLV
,
NULL
,
WL1271_CMD_TEMPL_MAX_SIZE
,
i
,
...
...
drivers/net/wireless/wl12xx/io.c
View file @
5928b91a
...
...
@@ -113,6 +113,7 @@ int wl1271_set_partition(struct wl1271 *wl,
return
0
;
}
EXPORT_SYMBOL_GPL
(
wl1271_set_partition
);
void
wl1271_io_reset
(
struct
wl1271
*
wl
)
{
...
...
drivers/net/wireless/wl12xx/main.c
View file @
5928b91a
...
...
@@ -336,7 +336,8 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
}
static
int
wl1271_reg_notify
(
struct
wiphy
*
wiphy
,
struct
regulatory_request
*
request
)
{
struct
regulatory_request
*
request
)
{
struct
ieee80211_supported_band
*
band
;
struct
ieee80211_channel
*
ch
;
int
i
;
...
...
@@ -569,7 +570,7 @@ static void wl1271_irq_work(struct work_struct *work)
/* Check if any tx blocks were freed */
if
(
!
test_bit
(
WL1271_FLAG_FW_TX_BUSY
,
&
wl
->
flags
)
&&
!
skb_queue_empty
(
&
wl
->
tx_queue
)
)
{
wl
->
tx_queue_count
)
{
/*
* In order to avoid starvation of the TX path,
* call the work function directly.
...
...
@@ -890,6 +891,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct
ieee80211_tx_info
*
txinfo
=
IEEE80211_SKB_CB
(
skb
);
struct
ieee80211_sta
*
sta
=
txinfo
->
control
.
sta
;
unsigned
long
flags
;
int
q
;
/*
* peek into the rates configured in the STA entry.
...
...
@@ -917,10 +919,12 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
set_bit
(
WL1271_FLAG_STA_RATES_CHANGED
,
&
wl
->
flags
);
}
#endif
wl
->
tx_queue_count
++
;
spin_unlock_irqrestore
(
&
wl
->
wl_lock
,
flags
);
/* queue the packet */
skb_queue_tail
(
&
wl
->
tx_queue
,
skb
);
q
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
skb
));
skb_queue_tail
(
&
wl
->
tx_queue
[
q
],
skb
);
/*
* The chip specific setup must run before the first TX packet -
...
...
@@ -934,7 +938,7 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* The workqueue is slow to process the tx_queue and we need stop
* the queue here, otherwise the queue will get too long.
*/
if
(
skb_queue_len
(
&
wl
->
tx_queue
)
>=
WL1271_TX_QUEUE_HIGH_WATERMARK
)
{
if
(
wl
->
tx_queue_count
>=
WL1271_TX_QUEUE_HIGH_WATERMARK
)
{
wl1271_debug
(
DEBUG_TX
,
"op_tx: stopping queues"
);
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
...
...
@@ -1064,6 +1068,16 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
strncpy
(
wiphy
->
fw_version
,
wl
->
chip
.
fw_ver
,
sizeof
(
wiphy
->
fw_version
));
/*
* Now we know if 11a is supported (info from the NVS), so disable
* 11a channels if not supported
*/
if
(
!
wl
->
enable_11a
)
wiphy
->
bands
[
IEEE80211_BAND_5GHZ
]
->
n_channels
=
0
;
wl1271_debug
(
DEBUG_MAC80211
,
"11a is %ssupported"
,
wl
->
enable_11a
?
""
:
"not "
);
out:
mutex_unlock
(
&
wl
->
mutex
);
...
...
@@ -1157,10 +1171,16 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
struct
wl1271
*
wl
=
hw
->
priv
;
mutex_lock
(
&
wl
->
mutex
);
/*
* wl->vif can be null here if someone shuts down the interface
* just when hardware recovery has been started.
*/
if
(
wl
->
vif
)
{
WARN_ON
(
wl
->
vif
!=
vif
);
__wl1271_op_remove_interface
(
wl
);
mutex_unlock
(
&
wl
->
mutex
);
}
mutex_unlock
(
&
wl
->
mutex
);
cancel_work_sync
(
&
wl
->
recovery_work
);
}
...
...
@@ -1801,21 +1821,21 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
return
ret
;
}
static
void
wl1271_ssid_set
(
struct
wl1271
*
wl
,
struct
sk_buff
*
beacon
)
static
void
wl1271_ssid_set
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
,
int
offset
)
{
u8
*
ptr
=
beacon
->
data
+
offsetof
(
struct
ieee80211_mgmt
,
u
.
beacon
.
variable
);
u8
*
ptr
=
skb
->
data
+
offset
;
/* find the location of the ssid in the beacon */
while
(
ptr
<
beacon
->
data
+
beacon
->
len
)
{
while
(
ptr
<
skb
->
data
+
skb
->
len
)
{
if
(
ptr
[
0
]
==
WLAN_EID_SSID
)
{
wl
->
ssid_len
=
ptr
[
1
];
memcpy
(
wl
->
ssid
,
ptr
+
2
,
wl
->
ssid_len
);
return
;
}
ptr
+=
ptr
[
1
]
;
ptr
+=
(
ptr
[
1
]
+
2
)
;
}
wl1271_error
(
"
ad-hoc beacon template has no SSID
!
\n
"
);
wl1271_error
(
"
No SSID in IEs
!
\n
"
);
}
static
void
wl1271_op_bss_info_changed
(
struct
ieee80211_hw
*
hw
,
...
...
@@ -1858,8 +1878,11 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if
(
beacon
)
{
struct
ieee80211_hdr
*
hdr
;
int
ieoffset
=
offsetof
(
struct
ieee80211_mgmt
,
u
.
beacon
.
variable
);
wl1271_ssid_set
(
wl
,
beacon
,
ieoffset
);
wl1271_ssid_set
(
wl
,
beacon
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_BEACON
,
beacon
->
data
,
beacon
->
len
,
0
,
...
...
@@ -1939,6 +1962,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
if
(
changed
&
BSS_CHANGED_ASSOC
)
{
if
(
bss_conf
->
assoc
)
{
u32
rates
;
int
ieoffset
;
wl
->
aid
=
bss_conf
->
aid
;
set_assoc
=
true
;
...
...
@@ -1967,13 +1991,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
goto
out_sleep
;
/*
* The SSID is intentionally set to NULL here - the
* firmware will set the probe request with a
* broadcast SSID regardless of what we set in the
* template.
* Get a template for hardware connection maintenance
*/
ret
=
wl1271_cmd_build_probe_req
(
wl
,
NULL
,
0
,
NULL
,
0
,
wl
->
band
);
dev_kfree_skb
(
wl
->
probereq
);
wl
->
probereq
=
wl1271_cmd_build_ap_probe_req
(
wl
,
NULL
);
ieoffset
=
offsetof
(
struct
ieee80211_mgmt
,
u
.
probe_req
.
variable
);
wl1271_ssid_set
(
wl
,
wl
->
probereq
,
ieoffset
);
/* enable the connection monitoring feature */
ret
=
wl1271_acx_conn_monit_params
(
wl
,
true
);
...
...
@@ -1996,6 +2020,10 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
clear_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
wl
->
aid
=
0
;
/* free probe-request template */
dev_kfree_skb
(
wl
->
probereq
);
wl
->
probereq
=
NULL
;
/* re-enable dynamic ps - just in case */
ieee80211_enable_dyn_ps
(
wl
->
vif
);
...
...
@@ -2085,10 +2113,26 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
__be32
addr
=
bss_conf
->
arp_addr_list
[
0
];
WARN_ON
(
wl
->
bss_type
!=
BSS_TYPE_STA_BSS
);
if
(
bss_conf
->
arp_addr_cnt
==
1
&&
bss_conf
->
arp_filter_enabled
)
ret
=
wl1271_acx_arp_ip_filter
(
wl
,
true
,
addr
);
else
ret
=
wl1271_acx_arp_ip_filter
(
wl
,
false
,
addr
);
if
(
bss_conf
->
arp_addr_cnt
==
1
&&
bss_conf
->
arp_filter_enabled
)
{
/*
* The template should have been configured only upon
* association. however, it seems that the correct ip
* isn't being set (when sending), so we have to
* reconfigure the template upon every ip change.
*/
ret
=
wl1271_cmd_build_arp_rsp
(
wl
,
addr
);
if
(
ret
<
0
)
{
wl1271_warning
(
"build arp rsp failed: %d"
,
ret
);
goto
out_sleep
;
}
ret
=
wl1271_acx_arp_ip_filter
(
wl
,
(
ACX_ARP_FILTER_ARP_FILTERING
|
ACX_ARP_FILTER_AUTO_ARP
),
addr
);
}
else
ret
=
wl1271_acx_arp_ip_filter
(
wl
,
0
,
addr
);
if
(
ret
<
0
)
goto
out_sleep
;
...
...
@@ -2353,14 +2397,6 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = {
/* 5 GHz band channels for WL1273 */
static
struct
ieee80211_channel
wl1271_channels_5ghz
[]
=
{
{
.
hw_value
=
183
,
.
center_freq
=
4915
},
{
.
hw_value
=
184
,
.
center_freq
=
4920
},
{
.
hw_value
=
185
,
.
center_freq
=
4925
},
{
.
hw_value
=
187
,
.
center_freq
=
4935
},
{
.
hw_value
=
188
,
.
center_freq
=
4940
},
{
.
hw_value
=
189
,
.
center_freq
=
4945
},
{
.
hw_value
=
192
,
.
center_freq
=
4960
},
{
.
hw_value
=
196
,
.
center_freq
=
4980
},
{
.
hw_value
=
7
,
.
center_freq
=
5035
},
{
.
hw_value
=
8
,
.
center_freq
=
5040
},
{
.
hw_value
=
9
,
.
center_freq
=
5045
},
...
...
@@ -2581,6 +2617,8 @@ int wl1271_register_hw(struct wl1271 *wl)
wl
->
mac80211_registered
=
true
;
wl1271_debugfs_init
(
wl
);
register_netdevice_notifier
(
&
wl1271_dev_notifier
);
wl1271_notice
(
"loaded"
);
...
...
@@ -2631,6 +2669,13 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
wl
->
hw
->
wiphy
->
interface_modes
=
BIT
(
NL80211_IFTYPE_STATION
)
|
BIT
(
NL80211_IFTYPE_ADHOC
);
wl
->
hw
->
wiphy
->
max_scan_ssids
=
1
;
/*
* Maximum length of elements in scanning probe request templates
* should be the maximum length possible for a template, without
* the IEEE80211 header of the template
*/
wl
->
hw
->
wiphy
->
max_scan_ie_len
=
WL1271_CMD_TEMPL_MAX_SIZE
-
sizeof
(
struct
ieee80211_header
);
wl
->
hw
->
wiphy
->
bands
[
IEEE80211_BAND_2GHZ
]
=
&
wl1271_band_2ghz
;
wl
->
hw
->
wiphy
->
bands
[
IEEE80211_BAND_5GHZ
]
=
&
wl1271_band_5ghz
;
...
...
@@ -2677,7 +2722,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
hw
=
hw
;
wl
->
plat_dev
=
plat_dev
;
skb_queue_head_init
(
&
wl
->
tx_queue
);
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
skb_queue_head_init
(
&
wl
->
tx_queue
[
i
]);
INIT_DELAYED_WORK
(
&
wl
->
elp_work
,
wl1271_elp_work
);
INIT_DELAYED_WORK
(
&
wl
->
pspoll_work
,
wl1271_pspoll_work
);
...
...
@@ -2715,8 +2761,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
/* Apply default driver configuration. */
wl1271_conf_init
(
wl
);
wl1271_debugfs_init
(
wl
);
order
=
get_order
(
WL1271_AGGR_BUFFER_SIZE
);
wl
->
aggr_buf
=
(
u8
*
)
__get_free_pages
(
GFP_KERNEL
,
order
);
if
(
!
wl
->
aggr_buf
)
{
...
...
@@ -2793,6 +2837,11 @@ int wl1271_free_hw(struct wl1271 *wl)
}
EXPORT_SYMBOL_GPL
(
wl1271_free_hw
);
u32
wl12xx_debug_level
;
EXPORT_SYMBOL_GPL
(
wl12xx_debug_level
);
module_param_named
(
debug_level
,
wl12xx_debug_level
,
uint
,
DEBUG_NONE
);
MODULE_PARM_DESC
(
debug_level
,
"wl12xx debugging level"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <luciano.coelho@nokia.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
drivers/net/wireless/wl12xx/scan.c
View file @
5928b91a
...
...
@@ -51,6 +51,10 @@ void wl1271_scan_complete_work(struct work_struct *work)
wl
->
scan
.
req
=
NULL
;
ieee80211_scan_completed
(
wl
->
hw
,
false
);
/* restore hardware connection monitoring template */
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
wl1271_cmd_build_ap_probe_req
(
wl
,
wl
->
probereq
);
if
(
wl
->
scan
.
failed
)
{
wl1271_info
(
"Scan completed due to error."
);
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
...
...
drivers/net/wireless/wl12xx/sdio_test.c
0 → 100644
View file @
5928b91a
/*
* SDIO testing driver for wl12xx
*
* Copyright (C) 2010 Nokia Corporation
*
* Contact: Roger Quadros <roger.quadros@nokia.com>
*
* wl12xx read/write routines taken from the main module
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/crc7.h>
#include <linux/vmalloc.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/card.h>
#include <linux/gpio.h>
#include <linux/wl12xx.h>
#include <linux/kthread.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
#include "wl12xx.h"
#include "io.h"
#include "boot.h"
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
#endif
#ifndef SDIO_DEVICE_ID_TI_WL1271
#define SDIO_DEVICE_ID_TI_WL1271 0x4076
#endif
static
bool
rx
,
tx
;
module_param
(
rx
,
bool
,
S_IRUGO
|
S_IWUSR
);
MODULE_PARM_DESC
(
rx
,
"Perform rx test. Default (0). "
"This test continuously reads data from the SDIO device.
\n
"
);
module_param
(
tx
,
bool
,
S_IRUGO
|
S_IWUSR
);
MODULE_PARM_DESC
(
tx
,
"Perform tx test. Default (0). "
"This test continuously writes data to the SDIO device.
\n
"
);
struct
wl1271_test
{
struct
wl1271
wl
;
struct
task_struct
*
test_task
;
};
static
const
struct
sdio_device_id
wl1271_devices
[]
=
{
{
SDIO_DEVICE
(
SDIO_VENDOR_ID_TI
,
SDIO_DEVICE_ID_TI_WL1271
)
},
{}
};
static
inline
struct
sdio_func
*
wl_to_func
(
struct
wl1271
*
wl
)
{
return
wl
->
if_priv
;
}
static
struct
device
*
wl1271_sdio_wl_to_dev
(
struct
wl1271
*
wl
)
{
return
&
(
wl_to_func
(
wl
)
->
dev
);
}
static
void
wl1271_sdio_raw_read
(
struct
wl1271
*
wl
,
int
addr
,
void
*
buf
,
size_t
len
,
bool
fixed
)
{
int
ret
=
0
;
struct
sdio_func
*
func
=
wl_to_func
(
wl
);
if
(
unlikely
(
addr
==
HW_ACCESS_ELP_CTRL_REG_ADDR
))
{
((
u8
*
)
buf
)[
0
]
=
sdio_f0_readb
(
func
,
addr
,
&
ret
);
wl1271_debug
(
DEBUG_SDIO
,
"sdio read 52 addr 0x%x, byte 0x%02x"
,
addr
,
((
u8
*
)
buf
)[
0
]);
}
else
{
if
(
fixed
)
ret
=
sdio_readsb
(
func
,
buf
,
addr
,
len
);
else
ret
=
sdio_memcpy_fromio
(
func
,
buf
,
addr
,
len
);
wl1271_debug
(
DEBUG_SDIO
,
"sdio read 53 addr 0x%x, %zu bytes"
,
addr
,
len
);
wl1271_dump_ascii
(
DEBUG_SDIO
,
"data: "
,
buf
,
len
);
}
if
(
ret
)
wl1271_error
(
"sdio read failed (%d)"
,
ret
);
}
static
void
wl1271_sdio_raw_write
(
struct
wl1271
*
wl
,
int
addr
,
void
*
buf
,
size_t
len
,
bool
fixed
)
{
int
ret
=
0
;
struct
sdio_func
*
func
=
wl_to_func
(
wl
);
if
(
unlikely
(
addr
==
HW_ACCESS_ELP_CTRL_REG_ADDR
))
{
sdio_f0_writeb
(
func
,
((
u8
*
)
buf
)[
0
],
addr
,
&
ret
);
wl1271_debug
(
DEBUG_SDIO
,
"sdio write 52 addr 0x%x, byte 0x%02x"
,
addr
,
((
u8
*
)
buf
)[
0
]);
}
else
{
wl1271_debug
(
DEBUG_SDIO
,
"sdio write 53 addr 0x%x, %zu bytes"
,
addr
,
len
);
wl1271_dump_ascii
(
DEBUG_SDIO
,
"data: "
,
buf
,
len
);
if
(
fixed
)
ret
=
sdio_writesb
(
func
,
addr
,
buf
,
len
);
else
ret
=
sdio_memcpy_toio
(
func
,
addr
,
buf
,
len
);
}
if
(
ret
)
wl1271_error
(
"sdio write failed (%d)"
,
ret
);
}
static
int
wl1271_sdio_set_power
(
struct
wl1271
*
wl
,
bool
enable
)
{
struct
sdio_func
*
func
=
wl_to_func
(
wl
);
int
ret
;
/* Let the SDIO stack handle wlan_enable control, so we
* keep host claimed while wlan is in use to keep wl1271
* alive.
*/
if
(
enable
)
{
/* Power up the card */
ret
=
pm_runtime_get_sync
(
&
func
->
dev
);
if
(
ret
<
0
)
goto
out
;
sdio_claim_host
(
func
);
sdio_enable_func
(
func
);
sdio_release_host
(
func
);
}
else
{
sdio_claim_host
(
func
);
sdio_disable_func
(
func
);
sdio_release_host
(
func
);
/* Power down the card */
ret
=
pm_runtime_put_sync
(
&
func
->
dev
);
}
out:
return
ret
;
}
static
void
wl1271_sdio_disable_interrupts
(
struct
wl1271
*
wl
)
{
}
static
void
wl1271_sdio_enable_interrupts
(
struct
wl1271
*
wl
)
{
}
static
struct
wl1271_if_operations
sdio_ops
=
{
.
read
=
wl1271_sdio_raw_read
,
.
write
=
wl1271_sdio_raw_write
,
.
power
=
wl1271_sdio_set_power
,
.
dev
=
wl1271_sdio_wl_to_dev
,
.
enable_irq
=
wl1271_sdio_enable_interrupts
,
.
disable_irq
=
wl1271_sdio_disable_interrupts
,
};
static
void
wl1271_fw_wakeup
(
struct
wl1271
*
wl
)
{
u32
elp_reg
;
elp_reg
=
ELPCTRL_WAKE_UP
;
wl1271_raw_write32
(
wl
,
HW_ACCESS_ELP_CTRL_REG_ADDR
,
elp_reg
);
}
static
int
wl1271_fetch_firmware
(
struct
wl1271
*
wl
)
{
const
struct
firmware
*
fw
;
int
ret
;
ret
=
request_firmware
(
&
fw
,
WL1271_FW_NAME
,
wl1271_wl_to_dev
(
wl
));
if
(
ret
<
0
)
{
wl1271_error
(
"could not get firmware: %d"
,
ret
);
return
ret
;
}
if
(
fw
->
size
%
4
)
{
wl1271_error
(
"firmware size is not multiple of 32 bits: %zu"
,
fw
->
size
);
ret
=
-
EILSEQ
;
goto
out
;
}
wl
->
fw_len
=
fw
->
size
;
wl
->
fw
=
vmalloc
(
wl
->
fw_len
);
if
(
!
wl
->
fw
)
{
wl1271_error
(
"could not allocate memory for the firmware"
);
ret
=
-
ENOMEM
;
goto
out
;
}
memcpy
(
wl
->
fw
,
fw
->
data
,
wl
->
fw_len
);
ret
=
0
;
out:
release_firmware
(
fw
);
return
ret
;
}
static
int
wl1271_fetch_nvs
(
struct
wl1271
*
wl
)
{
const
struct
firmware
*
fw
;
int
ret
;
ret
=
request_firmware
(
&
fw
,
WL1271_NVS_NAME
,
wl1271_wl_to_dev
(
wl
));
if
(
ret
<
0
)
{
wl1271_error
(
"could not get nvs file: %d"
,
ret
);
return
ret
;
}
wl
->
nvs
=
kmemdup
(
fw
->
data
,
sizeof
(
struct
wl1271_nvs_file
),
GFP_KERNEL
);
if
(
!
wl
->
nvs
)
{
wl1271_error
(
"could not allocate memory for the nvs file"
);
ret
=
-
ENOMEM
;
goto
out
;
}
wl
->
nvs_len
=
fw
->
size
;
out:
release_firmware
(
fw
);
return
ret
;
}
static
int
wl1271_chip_wakeup
(
struct
wl1271
*
wl
)
{
struct
wl1271_partition_set
partition
;
int
ret
;
msleep
(
WL1271_PRE_POWER_ON_SLEEP
);
ret
=
wl1271_power_on
(
wl
);
if
(
ret
)
return
ret
;
msleep
(
WL1271_POWER_ON_SLEEP
);
/* We don't need a real memory partition here, because we only want
* to use the registers at this point. */
memset
(
&
partition
,
0
,
sizeof
(
partition
));
partition
.
reg
.
start
=
REGISTERS_BASE
;
partition
.
reg
.
size
=
REGISTERS_DOWN_SIZE
;
wl1271_set_partition
(
wl
,
&
partition
);
/* ELP module wake up */
wl1271_fw_wakeup
(
wl
);
/* whal_FwCtrl_BootSm() */
/* 0. read chip id from CHIP_ID */
wl
->
chip
.
id
=
wl1271_read32
(
wl
,
CHIP_ID_B
);
/* 1. check if chip id is valid */
switch
(
wl
->
chip
.
id
)
{
case
CHIP_ID_1271_PG10
:
wl1271_warning
(
"chip id 0x%x (1271 PG10) support is obsolete"
,
wl
->
chip
.
id
);
break
;
case
CHIP_ID_1271_PG20
:
wl1271_notice
(
"chip id 0x%x (1271 PG20)"
,
wl
->
chip
.
id
);
break
;
default:
wl1271_warning
(
"unsupported chip id: 0x%x"
,
wl
->
chip
.
id
);
return
-
ENODEV
;
}
return
ret
;
}
static
struct
wl1271_partition_set
part_down
=
{
.
mem
=
{
.
start
=
0x00000000
,
.
size
=
0x000177c0
},
.
reg
=
{
.
start
=
REGISTERS_BASE
,
.
size
=
0x00008800
},
.
mem2
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
.
mem3
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
};
static
int
tester
(
void
*
data
)
{
struct
wl1271
*
wl
=
data
;
struct
sdio_func
*
func
=
wl_to_func
(
wl
);
struct
device
*
pdev
=
&
func
->
dev
;
int
ret
=
0
;
bool
rx_started
=
0
;
bool
tx_started
=
0
;
uint8_t
*
tx_buf
,
*
rx_buf
;
int
test_size
=
PAGE_SIZE
;
u32
addr
=
0
;
struct
wl1271_partition_set
partition
;
/* We assume chip is powered up and firmware fetched */
memcpy
(
&
partition
,
&
part_down
,
sizeof
(
partition
));
partition
.
mem
.
start
=
addr
;
wl1271_set_partition
(
wl
,
&
partition
);
tx_buf
=
kmalloc
(
test_size
,
GFP_KERNEL
);
rx_buf
=
kmalloc
(
test_size
,
GFP_KERNEL
);
if
(
!
tx_buf
||
!
rx_buf
)
{
dev_err
(
pdev
,
"Could not allocate memory. Test will not run.
\n
"
);
ret
=
-
ENOMEM
;
goto
free
;
}
memset
(
tx_buf
,
0x5a
,
test_size
);
/* write something in data area so we can read it back */
wl1271_write
(
wl
,
addr
,
tx_buf
,
test_size
,
false
);
while
(
!
kthread_should_stop
())
{
if
(
rx
&&
!
rx_started
)
{
dev_info
(
pdev
,
"starting rx test
\n
"
);
rx_started
=
1
;
}
else
if
(
!
rx
&&
rx_started
)
{
dev_info
(
pdev
,
"stopping rx test
\n
"
);
rx_started
=
0
;
}
if
(
tx
&&
!
tx_started
)
{
dev_info
(
pdev
,
"starting tx test
\n
"
);
tx_started
=
1
;
}
else
if
(
!
tx
&&
tx_started
)
{
dev_info
(
pdev
,
"stopping tx test
\n
"
);
tx_started
=
0
;
}
if
(
rx_started
)
wl1271_read
(
wl
,
addr
,
rx_buf
,
test_size
,
false
);
if
(
tx_started
)
wl1271_write
(
wl
,
addr
,
tx_buf
,
test_size
,
false
);
if
(
!
rx_started
&&
!
tx_started
)
msleep
(
100
);
}
free:
kfree
(
tx_buf
);
kfree
(
rx_buf
);
return
ret
;
}
static
int
__devinit
wl1271_probe
(
struct
sdio_func
*
func
,
const
struct
sdio_device_id
*
id
)
{
const
struct
wl12xx_platform_data
*
wlan_data
;
struct
wl1271
*
wl
;
struct
wl1271_test
*
wl_test
;
int
ret
=
0
;
/* wl1271 has 2 sdio functions we handle just the wlan part */
if
(
func
->
num
!=
0x02
)
return
-
ENODEV
;
wl_test
=
kzalloc
(
sizeof
(
struct
wl1271_test
),
GFP_KERNEL
);
if
(
!
wl_test
)
{
dev_err
(
&
func
->
dev
,
"Could not allocate memory
\n
"
);
return
-
ENOMEM
;
}
wl
=
&
wl_test
->
wl
;
wl
->
if_priv
=
func
;
wl
->
if_ops
=
&
sdio_ops
;
/* Grab access to FN0 for ELP reg. */
func
->
card
->
quirks
|=
MMC_QUIRK_LENIENT_FN0
;
wlan_data
=
wl12xx_get_platform_data
();
if
(
IS_ERR
(
wlan_data
))
{
ret
=
PTR_ERR
(
wlan_data
);
dev_err
(
&
func
->
dev
,
"missing wlan platform data: %d
\n
"
,
ret
);
goto
out_free
;
}
wl
->
irq
=
wlan_data
->
irq
;
wl
->
ref_clock
=
wlan_data
->
board_ref_clock
;
sdio_set_drvdata
(
func
,
wl_test
);
/* power up the device */
ret
=
wl1271_chip_wakeup
(
wl
);
if
(
ret
)
{
dev_err
(
&
func
->
dev
,
"could not wake up chip
\n
"
);
goto
out_free
;
}
if
(
wl
->
fw
==
NULL
)
{
ret
=
wl1271_fetch_firmware
(
wl
);
if
(
ret
<
0
)
{
dev_err
(
&
func
->
dev
,
"firmware fetch error
\n
"
);
goto
out_off
;
}
}
/* fetch NVS */
if
(
wl
->
nvs
==
NULL
)
{
ret
=
wl1271_fetch_nvs
(
wl
);
if
(
ret
<
0
)
{
dev_err
(
&
func
->
dev
,
"NVS fetch error
\n
"
);
goto
out_off
;
}
}
ret
=
wl1271_load_firmware
(
wl
);
if
(
ret
<
0
)
{
dev_err
(
&
func
->
dev
,
"firmware load error: %d
\n
"
,
ret
);
goto
out_free
;
}
dev_info
(
&
func
->
dev
,
"initialized
\n
"
);
/* I/O testing will be done in the tester thread */
wl_test
->
test_task
=
kthread_run
(
tester
,
wl
,
"sdio_tester"
);
if
(
IS_ERR
(
wl_test
->
test_task
))
{
dev_err
(
&
func
->
dev
,
"unable to create kernel thread
\n
"
);
ret
=
PTR_ERR
(
wl_test
->
test_task
);
goto
out_free
;
}
return
0
;
out_off:
/* power off the chip */
wl1271_power_off
(
wl
);
out_free:
kfree
(
wl_test
);
return
ret
;
}
static
void
__devexit
wl1271_remove
(
struct
sdio_func
*
func
)
{
struct
wl1271_test
*
wl_test
=
sdio_get_drvdata
(
func
);
/* stop the I/O test thread */
kthread_stop
(
wl_test
->
test_task
);
/* power off the chip */
wl1271_power_off
(
&
wl_test
->
wl
);
vfree
(
wl_test
->
wl
.
fw
);
wl_test
->
wl
.
fw
=
NULL
;
kfree
(
wl_test
->
wl
.
nvs
);
wl_test
->
wl
.
nvs
=
NULL
;
kfree
(
wl_test
);
}
static
struct
sdio_driver
wl1271_sdio_driver
=
{
.
name
=
"wl12xx_sdio_test"
,
.
id_table
=
wl1271_devices
,
.
probe
=
wl1271_probe
,
.
remove
=
__devexit_p
(
wl1271_remove
),
};
static
int
__init
wl1271_init
(
void
)
{
int
ret
;
ret
=
sdio_register_driver
(
&
wl1271_sdio_driver
);
if
(
ret
<
0
)
pr_err
(
"failed to register sdio driver: %d
\n
"
,
ret
);
return
ret
;
}
module_init
(
wl1271_init
);
static
void
__exit
wl1271_exit
(
void
)
{
sdio_unregister_driver
(
&
wl1271_sdio_driver
);
}
module_exit
(
wl1271_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Roger Quadros <roger.quadros@nokia.com>"
);
drivers/net/wireless/wl12xx/tx.c
View file @
5928b91a
...
...
@@ -125,7 +125,6 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
/* queue (we use same identifiers for tid's and ac's */
ac
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
skb
));
desc
->
tid
=
ac
;
desc
->
aid
=
TX_HW_DEFAULT_AID
;
desc
->
reserved
=
0
;
...
...
@@ -228,7 +227,7 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
unsigned
long
flags
;
if
(
test_bit
(
WL1271_FLAG_TX_QUEUE_STOPPED
,
&
wl
->
flags
)
&&
skb_queue_len
(
&
wl
->
tx_queue
)
<=
WL1271_TX_QUEUE_LOW_WATERMARK
)
{
wl
->
tx_queue_count
<=
WL1271_TX_QUEUE_LOW_WATERMARK
)
{
/* firmware buffer has space, restart queues */
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
ieee80211_wake_queues
(
wl
->
hw
);
...
...
@@ -237,6 +236,43 @@ static void handle_tx_low_watermark(struct wl1271 *wl)
}
}
static
struct
sk_buff
*
wl1271_skb_dequeue
(
struct
wl1271
*
wl
)
{
struct
sk_buff
*
skb
=
NULL
;
unsigned
long
flags
;
skb
=
skb_dequeue
(
&
wl
->
tx_queue
[
CONF_TX_AC_VO
]);
if
(
skb
)
goto
out
;
skb
=
skb_dequeue
(
&
wl
->
tx_queue
[
CONF_TX_AC_VI
]);
if
(
skb
)
goto
out
;
skb
=
skb_dequeue
(
&
wl
->
tx_queue
[
CONF_TX_AC_BE
]);
if
(
skb
)
goto
out
;
skb
=
skb_dequeue
(
&
wl
->
tx_queue
[
CONF_TX_AC_BK
]);
out:
if
(
skb
)
{
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
wl
->
tx_queue_count
--
;
spin_unlock_irqrestore
(
&
wl
->
wl_lock
,
flags
);
}
return
skb
;
}
static
void
wl1271_skb_queue_head
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
unsigned
long
flags
;
int
q
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
skb
));
skb_queue_head
(
&
wl
->
tx_queue
[
q
],
skb
);
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
wl
->
tx_queue_count
++
;
spin_unlock_irqrestore
(
&
wl
->
wl_lock
,
flags
);
}
void
wl1271_tx_work_locked
(
struct
wl1271
*
wl
)
{
struct
sk_buff
*
skb
;
...
...
@@ -270,7 +306,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
wl1271_acx_rate_policies
(
wl
);
}
while
((
skb
=
skb_dequeue
(
&
wl
->
tx_queue
)))
{
while
((
skb
=
wl1271_skb_dequeue
(
wl
)))
{
if
(
!
woken_up
)
{
ret
=
wl1271_ps_elp_wakeup
(
wl
,
false
);
if
(
ret
<
0
)
...
...
@@ -284,7 +320,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
* Aggregation buffer is full.
* Flush buffer and try again.
*/
skb_queue_head
(
&
wl
->
tx_queue
,
skb
);
wl1271_skb_queue_head
(
wl
,
skb
);
wl1271_write
(
wl
,
WL1271_SLV_MEM_DATA
,
wl
->
aggr_buf
,
buf_offset
,
true
);
sent_packets
=
true
;
...
...
@@ -295,7 +331,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
* Firmware buffer is full.
* Queue back last skb, and stop aggregating.
*/
skb_queue_head
(
&
wl
->
tx_queue
,
skb
);
wl1271_skb_queue_head
(
wl
,
skb
);
/* No work left, avoid scheduling redundant tx work */
set_bit
(
WL1271_FLAG_FW_TX_BUSY
,
&
wl
->
flags
);
goto
out_ack
;
...
...
@@ -440,10 +476,13 @@ void wl1271_tx_reset(struct wl1271 *wl)
struct
sk_buff
*
skb
;
/* TX failure */
while
((
skb
=
skb_dequeue
(
&
wl
->
tx_queue
)))
{
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
while
((
skb
=
skb_dequeue
(
&
wl
->
tx_queue
[
i
])))
{
wl1271_debug
(
DEBUG_TX
,
"freeing skb 0x%p"
,
skb
);
ieee80211_tx_status
(
wl
->
hw
,
skb
);
}
}
wl
->
tx_queue_count
=
0
;
/*
* Make sure the driver is at a consistent state, in case this
...
...
@@ -472,8 +511,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
mutex_lock
(
&
wl
->
mutex
);
wl1271_debug
(
DEBUG_TX
,
"flushing tx buffer: %d"
,
wl
->
tx_frames_cnt
);
if
((
wl
->
tx_frames_cnt
==
0
)
&&
skb_queue_empty
(
&
wl
->
tx_queue
))
{
if
((
wl
->
tx_frames_cnt
==
0
)
&&
(
wl
->
tx_queue_count
==
0
))
{
mutex_unlock
(
&
wl
->
mutex
);
return
;
}
...
...
drivers/net/wireless/wl12xx/wl12xx.h
View file @
5928b91a
...
...
@@ -60,31 +60,32 @@ enum {
DEBUG_ALL
=
~
0
,
};
#define DEBUG_LEVEL (DEBUG_NONE)
extern
u32
wl12xx_debug_level
;
#define DEBUG_DUMP_LIMIT 1024
#define wl1271_error(fmt, arg...) \
pr
intk(KERN_ERR
DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
pr
_err(
DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
#define wl1271_warning(fmt, arg...) \
pr
intk(KERN_WARNING
DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
pr
_warning(
DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
#define wl1271_notice(fmt, arg...) \
pr
intk(KERN_INFO
DRIVER_PREFIX fmt "\n", ##arg)
pr
_info(
DRIVER_PREFIX fmt "\n", ##arg)
#define wl1271_info(fmt, arg...) \
pr
intk(KERN_DEBUG
DRIVER_PREFIX fmt "\n", ##arg)
pr
_info(
DRIVER_PREFIX fmt "\n", ##arg)
#define wl1271_debug(level, fmt, arg...) \
do { \
if (level &
DEBUG_LEVEL
) \
pr
intk(KERN_DEBUG
DRIVER_PREFIX fmt "\n", ##arg); \
if (level &
wl12xx_debug_level
) \
pr
_debug(
DRIVER_PREFIX fmt "\n", ##arg); \
} while (0)
/* TODO: use pr_debug_hex_dump when it will be available */
#define wl1271_dump(level, prefix, buf, len) \
do { \
if (level &
DEBUG_LEVEL
) \
if (level &
wl12xx_debug_level
) \
print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
DUMP_PREFIX_OFFSET, 16, 1, \
buf, \
...
...
@@ -94,7 +95,7 @@ enum {
#define wl1271_dump_ascii(level, prefix, buf, len) \
do { \
if (level &
DEBUG_LEVEL
) \
if (level &
wl12xx_debug_level
) \
print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
DUMP_PREFIX_OFFSET, 16, 1, \
buf, \
...
...
@@ -174,108 +175,6 @@ struct wl1271_stats {
unsigned
int
excessive_retries
;
};
struct
wl1271_debugfs
{
struct
dentry
*
rootdir
;
struct
dentry
*
fw_statistics
;
struct
dentry
*
tx_internal_desc_overflow
;
struct
dentry
*
rx_out_of_mem
;
struct
dentry
*
rx_hdr_overflow
;
struct
dentry
*
rx_hw_stuck
;
struct
dentry
*
rx_dropped
;
struct
dentry
*
rx_fcs_err
;
struct
dentry
*
rx_xfr_hint_trig
;
struct
dentry
*
rx_path_reset
;
struct
dentry
*
rx_reset_counter
;
struct
dentry
*
dma_rx_requested
;
struct
dentry
*
dma_rx_errors
;
struct
dentry
*
dma_tx_requested
;
struct
dentry
*
dma_tx_errors
;
struct
dentry
*
isr_cmd_cmplt
;
struct
dentry
*
isr_fiqs
;
struct
dentry
*
isr_rx_headers
;
struct
dentry
*
isr_rx_mem_overflow
;
struct
dentry
*
isr_rx_rdys
;
struct
dentry
*
isr_irqs
;
struct
dentry
*
isr_tx_procs
;
struct
dentry
*
isr_decrypt_done
;
struct
dentry
*
isr_dma0_done
;
struct
dentry
*
isr_dma1_done
;
struct
dentry
*
isr_tx_exch_complete
;
struct
dentry
*
isr_commands
;
struct
dentry
*
isr_rx_procs
;
struct
dentry
*
isr_hw_pm_mode_changes
;
struct
dentry
*
isr_host_acknowledges
;
struct
dentry
*
isr_pci_pm
;
struct
dentry
*
isr_wakeups
;
struct
dentry
*
isr_low_rssi
;
struct
dentry
*
wep_addr_key_count
;
struct
dentry
*
wep_default_key_count
;
/* skipping wep.reserved */
struct
dentry
*
wep_key_not_found
;
struct
dentry
*
wep_decrypt_fail
;
struct
dentry
*
wep_packets
;
struct
dentry
*
wep_interrupt
;
struct
dentry
*
pwr_ps_enter
;
struct
dentry
*
pwr_elp_enter
;
struct
dentry
*
pwr_missing_bcns
;
struct
dentry
*
pwr_wake_on_host
;
struct
dentry
*
pwr_wake_on_timer_exp
;
struct
dentry
*
pwr_tx_with_ps
;
struct
dentry
*
pwr_tx_without_ps
;
struct
dentry
*
pwr_rcvd_beacons
;
struct
dentry
*
pwr_power_save_off
;
struct
dentry
*
pwr_enable_ps
;
struct
dentry
*
pwr_disable_ps
;
struct
dentry
*
pwr_fix_tsf_ps
;
/* skipping cont_miss_bcns_spread for now */
struct
dentry
*
pwr_rcvd_awake_beacons
;
struct
dentry
*
mic_rx_pkts
;
struct
dentry
*
mic_calc_failure
;
struct
dentry
*
aes_encrypt_fail
;
struct
dentry
*
aes_decrypt_fail
;
struct
dentry
*
aes_encrypt_packets
;
struct
dentry
*
aes_decrypt_packets
;
struct
dentry
*
aes_encrypt_interrupt
;
struct
dentry
*
aes_decrypt_interrupt
;
struct
dentry
*
event_heart_beat
;
struct
dentry
*
event_calibration
;
struct
dentry
*
event_rx_mismatch
;
struct
dentry
*
event_rx_mem_empty
;
struct
dentry
*
event_rx_pool
;
struct
dentry
*
event_oom_late
;
struct
dentry
*
event_phy_transmit_error
;
struct
dentry
*
event_tx_stuck
;
struct
dentry
*
ps_pspoll_timeouts
;
struct
dentry
*
ps_upsd_timeouts
;
struct
dentry
*
ps_upsd_max_sptime
;
struct
dentry
*
ps_upsd_max_apturn
;
struct
dentry
*
ps_pspoll_max_apturn
;
struct
dentry
*
ps_pspoll_utilization
;
struct
dentry
*
ps_upsd_utilization
;
struct
dentry
*
rxpipe_rx_prep_beacon_drop
;
struct
dentry
*
rxpipe_descr_host_int_trig_rx_data
;
struct
dentry
*
rxpipe_beacon_buffer_thres_host_int_trig_rx_data
;
struct
dentry
*
rxpipe_missed_beacon_host_int_trig_rx_data
;
struct
dentry
*
rxpipe_tx_xfr_host_int_trig_rx_data
;
struct
dentry
*
tx_queue_len
;
struct
dentry
*
retry_count
;
struct
dentry
*
excessive_retries
;
struct
dentry
*
gpio_power
;
};
#define NUM_TX_QUEUES 4
#define NUM_RX_PKT_DESC 8
...
...
@@ -393,7 +292,8 @@ struct wl1271 {
int
session_counter
;
/* Frames scheduled for transmission, not handled yet */
struct
sk_buff_head
tx_queue
;
struct
sk_buff_head
tx_queue
[
NUM_TX_QUEUES
];
int
tx_queue_count
;
struct
work_struct
tx_work
;
...
...
@@ -431,6 +331,9 @@ struct wl1271 {
struct
wl1271_scan
scan
;
struct
delayed_work
scan_complete_work
;
/* probe-req template for the current AP */
struct
sk_buff
*
probereq
;
/* Our association ID */
u16
aid
;
...
...
@@ -475,7 +378,7 @@ struct wl1271 {
int
last_rssi_event
;
struct
wl1271_stats
stats
;
struct
wl1271_debugfs
debugfs
;
struct
dentry
*
rootdir
;
__le32
buffer_32
;
u32
buffer_cmd
;
...
...
drivers/net/wireless/wl12xx/wl12xx_80211.h
View file @
5928b91a
...
...
@@ -2,6 +2,7 @@
#define __WL12XX_80211_H__
#include <linux/if_ether.h>
/* ETH_ALEN */
#include <linux/if_arp.h>
/* RATES */
#define IEEE80211_CCK_RATE_1MB 0x02
...
...
@@ -133,11 +134,17 @@ struct wl12xx_qos_null_data_template {
__le16
qos_ctl
;
}
__packed
;
struct
wl12xx_probe_req_template
{
struct
ieee80211_header
header
;
struct
wl12xx_ie_ssid
ssid
;
struct
wl12xx_ie_rates
rates
;
struct
wl12xx_ie_rates
ext_rates
;
struct
wl12xx_arp_rsp_template
{
struct
ieee80211_hdr_3addr
hdr
;
u8
llc_hdr
[
sizeof
(
rfc1042_header
)];
u16
llc_type
;
struct
arphdr
arp_hdr
;
u8
sender_hw
[
ETH_ALEN
];
u32
sender_ip
;
u8
target_hw
[
ETH_ALEN
];
u32
target_ip
;
}
__packed
;
...
...
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