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
9e49a9d3
Commit
9e49a9d3
authored
Jun 18, 2013
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linville' of
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
parents
0b21eb9a
789e90e5
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
367 additions
and
254 deletions
+367
-254
drivers/net/wireless/ti/wl1251/spi.c
drivers/net/wireless/ti/wl1251/spi.c
+4
-26
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wl18xx/main.c
+45
-2
drivers/net/wireless/ti/wl18xx/reg.h
drivers/net/wireless/ti/wl18xx/reg.h
+15
-0
drivers/net/wireless/ti/wlcore/Makefile
drivers/net/wireless/ti/wlcore/Makefile
+1
-1
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/main.c
+55
-210
drivers/net/wireless/ti/wlcore/ps.c
drivers/net/wireless/ti/wlcore/ps.c
+1
-1
drivers/net/wireless/ti/wlcore/spi.c
drivers/net/wireless/ti/wlcore/spi.c
+1
-13
drivers/net/wireless/ti/wlcore/sysfs.c
drivers/net/wireless/ti/wlcore/sysfs.c
+216
-0
drivers/net/wireless/ti/wlcore/sysfs.h
drivers/net/wireless/ti/wlcore/sysfs.h
+28
-0
drivers/net/wireless/ti/wlcore/tx.c
drivers/net/wireless/ti/wlcore/tx.c
+1
-1
No files found.
drivers/net/wireless/ti/wl1251/spi.c
View file @
9e49a9d3
...
...
@@ -93,8 +93,7 @@ static void wl1251_spi_wake(struct wl1251 *wl)
memset
(
&
t
,
0
,
sizeof
(
t
));
spi_message_init
(
&
m
);
/*
* Set WSPI_INIT_COMMAND
/* Set WSPI_INIT_COMMAND
* the data is being send from the MSB to LSB
*/
cmd
[
2
]
=
0xff
;
...
...
@@ -262,7 +261,8 @@ static int wl1251_spi_probe(struct spi_device *spi)
wl
->
if_ops
=
&
wl1251_spi_ops
;
/* This is the only SPI value that we need to set here, the rest
* comes from the board-peripherals file */
* comes from the board-peripherals file
*/
spi
->
bits_per_word
=
32
;
ret
=
spi_setup
(
spi
);
...
...
@@ -329,29 +329,7 @@ static struct spi_driver wl1251_spi_driver = {
.
remove
=
wl1251_spi_remove
,
};
static
int
__init
wl1251_spi_init
(
void
)
{
int
ret
;
ret
=
spi_register_driver
(
&
wl1251_spi_driver
);
if
(
ret
<
0
)
{
wl1251_error
(
"failed to register spi driver: %d"
,
ret
);
goto
out
;
}
out:
return
ret
;
}
static
void
__exit
wl1251_spi_exit
(
void
)
{
spi_unregister_driver
(
&
wl1251_spi_driver
);
wl1251_notice
(
"unloaded"
);
}
module_init
(
wl1251_spi_init
);
module_exit
(
wl1251_spi_exit
);
module_spi_driver
(
wl1251_spi_driver
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Kalle Valo <kvalo@adurom.com>"
);
...
...
drivers/net/wireless/ti/wl18xx/main.c
View file @
9e49a9d3
...
...
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/ip.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include "../wlcore/wlcore.h"
#include "../wlcore/debug.h"
...
...
@@ -594,8 +595,8 @@ static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
.
mem3
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
},
[
PART_PHY_INIT
]
=
{
.
mem
=
{
.
start
=
0x80926000
,
.
size
=
sizeof
(
struct
wl18xx_mac_and_phy_params
)
},
.
mem
=
{
.
start
=
WL18XX_PHY_INIT_MEM_ADDR
,
.
size
=
WL18XX_PHY_INIT_MEM_SIZE
},
.
reg
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
.
mem2
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
.
mem3
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
...
...
@@ -799,6 +800,9 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
u32
tmp
;
int
ret
;
BUILD_BUG_ON
(
sizeof
(
struct
wl18xx_mac_and_phy_params
)
>
WL18XX_PHY_INIT_MEM_SIZE
);
ret
=
wlcore_set_partition
(
wl
,
&
wl
->
ptable
[
PART_BOOT
]);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -815,6 +819,35 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
wl1271_debug
(
DEBUG_BOOT
,
"chip id 0x%x"
,
tmp
);
ret
=
wlcore_read32
(
wl
,
WL18XX_SCR_PAD2
,
&
tmp
);
if
(
ret
<
0
)
goto
out
;
/*
* Workaround for FDSP code RAM corruption (needed for PG2.1
* and newer; for older chips it's a NOP). Change FDSP clock
* settings so that it's muxed to the ATGP clock instead of
* its own clock.
*/
ret
=
wlcore_set_partition
(
wl
,
&
wl
->
ptable
[
PART_PHY_INIT
]);
if
(
ret
<
0
)
goto
out
;
/* disable FDSP clock */
ret
=
wlcore_write32
(
wl
,
WL18XX_PHY_FPGA_SPARE_1
,
MEM_FDSP_CLK_120_DISABLE
);
if
(
ret
<
0
)
goto
out
;
/* set ATPG clock toward FDSP Code RAM rather than its own clock */
ret
=
wlcore_write32
(
wl
,
WL18XX_PHY_FPGA_SPARE_1
,
MEM_FDSP_CODERAM_FUNC_CLK_SEL
);
if
(
ret
<
0
)
goto
out
;
/* re-enable FDSP clock */
ret
=
wlcore_write32
(
wl
,
WL18XX_PHY_FPGA_SPARE_1
,
MEM_FDSP_CLK_120_ENABLE
);
out:
return
ret
;
...
...
@@ -1286,6 +1319,16 @@ static int wl18xx_get_mac(struct wl1271 *wl)
((
mac1
&
0xff000000
)
>>
24
);
wl
->
fuse_nic_addr
=
(
mac1
&
0xffffff
);
if
(
!
wl
->
fuse_oui_addr
&&
!
wl
->
fuse_nic_addr
)
{
u8
mac
[
ETH_ALEN
];
eth_random_addr
(
mac
);
wl
->
fuse_oui_addr
=
(
mac
[
0
]
<<
16
)
+
(
mac
[
1
]
<<
8
)
+
mac
[
2
];
wl
->
fuse_nic_addr
=
(
mac
[
3
]
<<
16
)
+
(
mac
[
4
]
<<
8
)
+
mac
[
5
];
wl1271_warning
(
"MAC address from fuse not available, using random locally administered addresses."
);
}
ret
=
wlcore_set_partition
(
wl
,
&
wl
->
ptable
[
PART_DOWN
]);
out:
...
...
drivers/net/wireless/ti/wl18xx/reg.h
View file @
9e49a9d3
...
...
@@ -38,6 +38,9 @@
#define WL18XX_REG_BOOT_PART_SIZE 0x00014578
#define WL18XX_PHY_INIT_MEM_ADDR 0x80926000
#define WL18XX_PHY_END_MEM_ADDR 0x8093CA44
#define WL18XX_PHY_INIT_MEM_SIZE \
(WL18XX_PHY_END_MEM_ADDR - WL18XX_PHY_INIT_MEM_ADDR)
#define WL18XX_SDIO_WSPI_BASE (WL18XX_REGISTERS_BASE)
#define WL18XX_REG_CONFIG_BASE (WL18XX_REGISTERS_BASE + 0x02000)
...
...
@@ -217,4 +220,16 @@ static const char * const rdl_names[] = {
[
RDL_4_SP
]
=
"1897 MIMO"
,
};
/* FPGA_SPARE_1 register - used to change the PHY ATPG clock at boot time */
#define WL18XX_PHY_FPGA_SPARE_1 0x8093CA40
/* command to disable FDSP clock */
#define MEM_FDSP_CLK_120_DISABLE 0x80000000
/* command to set ATPG clock toward FDSP Code RAM rather than its own clock */
#define MEM_FDSP_CODERAM_FUNC_CLK_SEL 0xC0000000
/* command to re-enable FDSP clock */
#define MEM_FDSP_CLK_120_ENABLE 0x40000000
#endif
/* __REG_H__ */
drivers/net/wireless/ti/wlcore/Makefile
View file @
9e49a9d3
wlcore-objs
=
main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o
\
boot.o init.o debugfs.o scan.o
boot.o init.o debugfs.o scan.o
sysfs.o
wlcore_spi-objs
=
spi.o
wlcore_sdio-objs
=
sdio.o
...
...
drivers/net/wireless/ti/wlcore/main.c
View file @
9e49a9d3
/*
* This file is part of wl
1271
* This file is part of wl
core
*
* Copyright (C) 2008-2010 Nokia Corporation
*
* Contact: Luciano Coelho <luciano.coelho@nokia.com>
* Copyright (C) 2011-2013 Texas Instruments Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
...
...
@@ -24,34 +23,23 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/crc32.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/wl12xx.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include "wlcore.h"
#include "debug.h"
#include "wl12xx_80211.h"
#include "io.h"
#include "event.h"
#include "tx.h"
#include "rx.h"
#include "ps.h"
#include "init.h"
#include "debugfs.h"
#include "cmd.h"
#include "boot.h"
#include "testmode.h"
#include "scan.h"
#include "hw_ops.h"
#define WL1271_BOOT_RETRIES 3
#include "sysfs.h"
#define WL1271_BOOT_RETRIES 3
...
...
@@ -65,8 +53,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
static
void
wlcore_op_stop_locked
(
struct
wl1271
*
wl
);
static
void
wl1271_free_ap_keys
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
);
static
int
wl12xx_set_authorized
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
)
static
int
wl12xx_set_authorized
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
)
{
int
ret
;
...
...
@@ -983,7 +970,7 @@ static int wlcore_fw_wakeup(struct wl1271 *wl)
static
int
wl1271_setup
(
struct
wl1271
*
wl
)
{
wl
->
fw_status_1
=
k
m
alloc
(
WLCORE_FW_STATUS_1_LEN
(
wl
->
num_rx_desc
)
+
wl
->
fw_status_1
=
k
z
alloc
(
WLCORE_FW_STATUS_1_LEN
(
wl
->
num_rx_desc
)
+
sizeof
(
*
wl
->
fw_status_2
)
+
wl
->
fw_status_priv_len
,
GFP_KERNEL
);
if
(
!
wl
->
fw_status_1
)
...
...
@@ -993,7 +980,7 @@ static int wl1271_setup(struct wl1271 *wl)
(((
u8
*
)
wl
->
fw_status_1
)
+
WLCORE_FW_STATUS_1_LEN
(
wl
->
num_rx_desc
));
wl
->
tx_res_if
=
k
m
alloc
(
sizeof
(
*
wl
->
tx_res_if
),
GFP_KERNEL
);
wl
->
tx_res_if
=
k
z
alloc
(
sizeof
(
*
wl
->
tx_res_if
),
GFP_KERNEL
);
if
(
!
wl
->
tx_res_if
)
{
kfree
(
wl
->
fw_status_1
);
return
-
ENOMEM
;
...
...
@@ -1668,8 +1655,7 @@ static int wl1271_configure_suspend(struct wl1271 *wl,
return
0
;
}
static
void
wl1271_configure_resume
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
)
static
void
wl1271_configure_resume
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
)
{
int
ret
=
0
;
bool
is_ap
=
wlvif
->
bss_type
==
BSS_TYPE_AP_BSS
;
...
...
@@ -2603,6 +2589,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
cancel_work_sync
(
&
wlvif
->
rx_streaming_enable_work
);
cancel_work_sync
(
&
wlvif
->
rx_streaming_disable_work
);
cancel_delayed_work_sync
(
&
wlvif
->
connection_loss_work
);
cancel_delayed_work_sync
(
&
wlvif
->
channel_switch_work
);
mutex_lock
(
&
wl
->
mutex
);
}
...
...
@@ -3210,14 +3197,6 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if
(
ret
<
0
)
return
ret
;
/* the default WEP key needs to be configured at least once */
if
(
key_type
==
KEY_WEP
)
{
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
wlvif
->
default_key
,
wlvif
->
sta
.
hlid
);
if
(
ret
<
0
)
return
ret
;
}
}
return
0
;
...
...
@@ -3374,6 +3353,46 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
}
EXPORT_SYMBOL_GPL
(
wlcore_set_key
);
static
void
wl1271_op_set_default_key_idx
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
int
key_idx
)
{
struct
wl1271
*
wl
=
hw
->
priv
;
struct
wl12xx_vif
*
wlvif
=
wl12xx_vif_to_data
(
vif
);
int
ret
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 set default key idx %d"
,
key_idx
);
mutex_lock
(
&
wl
->
mutex
);
if
(
unlikely
(
wl
->
state
!=
WLCORE_STATE_ON
))
{
ret
=
-
EAGAIN
;
goto
out_unlock
;
}
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out_unlock
;
wlvif
->
default_key
=
key_idx
;
/* the default WEP key needs to be configured at least once */
if
(
wlvif
->
encryption_type
==
KEY_WEP
)
{
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
key_idx
,
wlvif
->
sta
.
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
}
out_sleep:
wl1271_ps_elp_sleep
(
wl
);
out_unlock:
mutex_unlock
(
&
wl
->
mutex
);
}
void
wlcore_regdomain_config
(
struct
wl1271
*
wl
)
{
int
ret
;
...
...
@@ -3782,8 +3801,7 @@ static int wlcore_set_beacon_template(struct wl1271 *wl,
struct
ieee80211_hdr
*
hdr
;
u32
min_rate
;
int
ret
;
int
ieoffset
=
offsetof
(
struct
ieee80211_mgmt
,
u
.
beacon
.
variable
);
int
ieoffset
=
offsetof
(
struct
ieee80211_mgmt
,
u
.
beacon
.
variable
);
struct
sk_buff
*
beacon
=
ieee80211_beacon_get
(
wl
->
hw
,
vif
);
u16
tmpl_id
;
...
...
@@ -4230,8 +4248,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
}
/* Handle new association with HT. Do this after join. */
if
(
sta_exists
&&
(
changed
&
BSS_CHANGED_HT
))
{
if
(
sta_exists
)
{
bool
enabled
=
bss_conf
->
chandef
.
width
!=
NL80211_CHAN_WIDTH_20_NOHT
;
...
...
@@ -5368,6 +5385,7 @@ static const struct ieee80211_ops wl1271_ops = {
.
ampdu_action
=
wl1271_op_ampdu_action
,
.
tx_frames_pending
=
wl1271_tx_frames_pending
,
.
set_bitrate_mask
=
wl12xx_set_bitrate_mask
,
.
set_default_unicast_key
=
wl1271_op_set_default_key_idx
,
.
channel_switch
=
wl12xx_op_channel_switch
,
.
flush
=
wlcore_op_flush
,
.
remain_on_channel
=
wlcore_op_remain_on_channel
,
...
...
@@ -5403,151 +5421,6 @@ u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band)
return
idx
;
}
static
ssize_t
wl1271_sysfs_show_bt_coex_state
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
ssize_t
len
;
len
=
PAGE_SIZE
;
mutex_lock
(
&
wl
->
mutex
);
len
=
snprintf
(
buf
,
len
,
"%d
\n\n
0 - off
\n
1 - on
\n
"
,
wl
->
sg_enabled
);
mutex_unlock
(
&
wl
->
mutex
);
return
len
;
}
static
ssize_t
wl1271_sysfs_store_bt_coex_state
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
unsigned
long
res
;
int
ret
;
ret
=
kstrtoul
(
buf
,
10
,
&
res
);
if
(
ret
<
0
)
{
wl1271_warning
(
"incorrect value written to bt_coex_mode"
);
return
count
;
}
mutex_lock
(
&
wl
->
mutex
);
res
=
!!
res
;
if
(
res
==
wl
->
sg_enabled
)
goto
out
;
wl
->
sg_enabled
=
res
;
if
(
unlikely
(
wl
->
state
!=
WLCORE_STATE_ON
))
goto
out
;
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
wl1271_acx_sg_enable
(
wl
,
wl
->
sg_enabled
);
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
DEVICE_ATTR
(
bt_coex_state
,
S_IRUGO
|
S_IWUSR
,
wl1271_sysfs_show_bt_coex_state
,
wl1271_sysfs_store_bt_coex_state
);
static
ssize_t
wl1271_sysfs_show_hw_pg_ver
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
ssize_t
len
;
len
=
PAGE_SIZE
;
mutex_lock
(
&
wl
->
mutex
);
if
(
wl
->
hw_pg_ver
>=
0
)
len
=
snprintf
(
buf
,
len
,
"%d
\n
"
,
wl
->
hw_pg_ver
);
else
len
=
snprintf
(
buf
,
len
,
"n/a
\n
"
);
mutex_unlock
(
&
wl
->
mutex
);
return
len
;
}
static
DEVICE_ATTR
(
hw_pg_ver
,
S_IRUGO
,
wl1271_sysfs_show_hw_pg_ver
,
NULL
);
static
ssize_t
wl1271_sysfs_read_fwlog
(
struct
file
*
filp
,
struct
kobject
*
kobj
,
struct
bin_attribute
*
bin_attr
,
char
*
buffer
,
loff_t
pos
,
size_t
count
)
{
struct
device
*
dev
=
container_of
(
kobj
,
struct
device
,
kobj
);
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
ssize_t
len
;
int
ret
;
ret
=
mutex_lock_interruptible
(
&
wl
->
mutex
);
if
(
ret
<
0
)
return
-
ERESTARTSYS
;
/* Let only one thread read the log at a time, blocking others */
while
(
wl
->
fwlog_size
==
0
)
{
DEFINE_WAIT
(
wait
);
prepare_to_wait_exclusive
(
&
wl
->
fwlog_waitq
,
&
wait
,
TASK_INTERRUPTIBLE
);
if
(
wl
->
fwlog_size
!=
0
)
{
finish_wait
(
&
wl
->
fwlog_waitq
,
&
wait
);
break
;
}
mutex_unlock
(
&
wl
->
mutex
);
schedule
();
finish_wait
(
&
wl
->
fwlog_waitq
,
&
wait
);
if
(
signal_pending
(
current
))
return
-
ERESTARTSYS
;
ret
=
mutex_lock_interruptible
(
&
wl
->
mutex
);
if
(
ret
<
0
)
return
-
ERESTARTSYS
;
}
/* Check if the fwlog is still valid */
if
(
wl
->
fwlog_size
<
0
)
{
mutex_unlock
(
&
wl
->
mutex
);
return
0
;
}
/* Seeking is not supported - old logs are not kept. Disregard pos. */
len
=
min
(
count
,
(
size_t
)
wl
->
fwlog_size
);
wl
->
fwlog_size
-=
len
;
memcpy
(
buffer
,
wl
->
fwlog
,
len
);
/* Make room for new messages */
memmove
(
wl
->
fwlog
,
wl
->
fwlog
+
len
,
wl
->
fwlog_size
);
mutex_unlock
(
&
wl
->
mutex
);
return
len
;
}
static
struct
bin_attribute
fwlog_attr
=
{
.
attr
=
{.
name
=
"fwlog"
,
.
mode
=
S_IRUSR
},
.
read
=
wl1271_sysfs_read_fwlog
,
};
static
void
wl12xx_derive_mac_addresses
(
struct
wl1271
*
wl
,
u32
oui
,
u32
nic
)
{
int
i
;
...
...
@@ -5827,8 +5700,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
return
0
;
}
#define WL1271_DEFAULT_CHANNEL 0
struct
ieee80211_hw
*
wlcore_alloc_hw
(
size_t
priv_size
,
u32
aggr_buf_size
,
u32
mbox_size
)
{
...
...
@@ -5881,7 +5752,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
goto
err_hw
;
}
wl
->
channel
=
WL1271_DEFAULT_CHANNEL
;
wl
->
channel
=
0
;
wl
->
rx_counter
=
0
;
wl
->
power_level
=
WL1271_DEFAULT_POWER_LEVEL
;
wl
->
band
=
IEEE80211_BAND_2GHZ
;
...
...
@@ -5988,11 +5859,8 @@ int wlcore_free_hw(struct wl1271 *wl)
wake_up_interruptible_all
(
&
wl
->
fwlog_waitq
);
mutex_unlock
(
&
wl
->
mutex
);
device_remove_bin_file
(
wl
->
dev
,
&
fwlog_attr
);
device_remove_file
(
wl
->
dev
,
&
dev_attr_hw_pg_ver
);
wlcore_sysfs_free
(
wl
);
device_remove_file
(
wl
->
dev
,
&
dev_attr_bt_coex_state
);
kfree
(
wl
->
buffer_32
);
kfree
(
wl
->
mbox
);
free_page
((
unsigned
long
)
wl
->
fwlog
);
...
...
@@ -6104,36 +5972,13 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
if
(
ret
)
goto
out_irq
;
/* Create sysfs file to control bt coex state */
ret
=
device_create_file
(
wl
->
dev
,
&
dev_attr_bt_coex_state
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to create sysfs file bt_coex_state"
);
ret
=
wlcore_sysfs_init
(
wl
);
if
(
ret
)
goto
out_unreg
;
}
/* Create sysfs file to get HW PG version */
ret
=
device_create_file
(
wl
->
dev
,
&
dev_attr_hw_pg_ver
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to create sysfs file hw_pg_ver"
);
goto
out_bt_coex_state
;
}
/* Create sysfs file for the FW log */
ret
=
device_create_bin_file
(
wl
->
dev
,
&
fwlog_attr
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to create sysfs file fwlog"
);
goto
out_hw_pg_ver
;
}
wl
->
initialized
=
true
;
goto
out
;
out_hw_pg_ver:
device_remove_file
(
wl
->
dev
,
&
dev_attr_hw_pg_ver
);
out_bt_coex_state:
device_remove_file
(
wl
->
dev
,
&
dev_attr_bt_coex_state
);
out_unreg:
wl1271_unregister_hw
(
wl
);
...
...
drivers/net/wireless/ti/wlcore/ps.c
View file @
9e49a9d3
...
...
@@ -110,7 +110,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
DECLARE_COMPLETION_ONSTACK
(
compl
);
unsigned
long
flags
;
int
ret
;
u
32
start_time
=
jiffies
;
u
nsigned
long
start_time
=
jiffies
;
bool
pending
=
false
;
/*
...
...
drivers/net/wireless/ti/wlcore/spi.c
View file @
9e49a9d3
...
...
@@ -434,19 +434,7 @@ static struct spi_driver wl1271_spi_driver = {
.
remove
=
wl1271_remove
,
};
static
int
__init
wl1271_init
(
void
)
{
return
spi_register_driver
(
&
wl1271_spi_driver
);
}
static
void
__exit
wl1271_exit
(
void
)
{
spi_unregister_driver
(
&
wl1271_spi_driver
);
}
module_init
(
wl1271_init
);
module_exit
(
wl1271_exit
);
module_spi_driver
(
wl1271_spi_driver
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
...
...
drivers/net/wireless/ti/wlcore/sysfs.c
0 → 100644
View file @
9e49a9d3
/*
* This file is part of wlcore
*
* Copyright (C) 2013 Texas Instruments Inc.
*
* 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 "wlcore.h"
#include "debug.h"
#include "ps.h"
#include "sysfs.h"
static
ssize_t
wl1271_sysfs_show_bt_coex_state
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
ssize_t
len
;
len
=
PAGE_SIZE
;
mutex_lock
(
&
wl
->
mutex
);
len
=
snprintf
(
buf
,
len
,
"%d
\n\n
0 - off
\n
1 - on
\n
"
,
wl
->
sg_enabled
);
mutex_unlock
(
&
wl
->
mutex
);
return
len
;
}
static
ssize_t
wl1271_sysfs_store_bt_coex_state
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
unsigned
long
res
;
int
ret
;
ret
=
kstrtoul
(
buf
,
10
,
&
res
);
if
(
ret
<
0
)
{
wl1271_warning
(
"incorrect value written to bt_coex_mode"
);
return
count
;
}
mutex_lock
(
&
wl
->
mutex
);
res
=
!!
res
;
if
(
res
==
wl
->
sg_enabled
)
goto
out
;
wl
->
sg_enabled
=
res
;
if
(
unlikely
(
wl
->
state
!=
WLCORE_STATE_ON
))
goto
out
;
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
wl1271_acx_sg_enable
(
wl
,
wl
->
sg_enabled
);
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
DEVICE_ATTR
(
bt_coex_state
,
S_IRUGO
|
S_IWUSR
,
wl1271_sysfs_show_bt_coex_state
,
wl1271_sysfs_store_bt_coex_state
);
static
ssize_t
wl1271_sysfs_show_hw_pg_ver
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
ssize_t
len
;
len
=
PAGE_SIZE
;
mutex_lock
(
&
wl
->
mutex
);
if
(
wl
->
hw_pg_ver
>=
0
)
len
=
snprintf
(
buf
,
len
,
"%d
\n
"
,
wl
->
hw_pg_ver
);
else
len
=
snprintf
(
buf
,
len
,
"n/a
\n
"
);
mutex_unlock
(
&
wl
->
mutex
);
return
len
;
}
static
DEVICE_ATTR
(
hw_pg_ver
,
S_IRUGO
,
wl1271_sysfs_show_hw_pg_ver
,
NULL
);
static
ssize_t
wl1271_sysfs_read_fwlog
(
struct
file
*
filp
,
struct
kobject
*
kobj
,
struct
bin_attribute
*
bin_attr
,
char
*
buffer
,
loff_t
pos
,
size_t
count
)
{
struct
device
*
dev
=
container_of
(
kobj
,
struct
device
,
kobj
);
struct
wl1271
*
wl
=
dev_get_drvdata
(
dev
);
ssize_t
len
;
int
ret
;
ret
=
mutex_lock_interruptible
(
&
wl
->
mutex
);
if
(
ret
<
0
)
return
-
ERESTARTSYS
;
/* Let only one thread read the log at a time, blocking others */
while
(
wl
->
fwlog_size
==
0
)
{
DEFINE_WAIT
(
wait
);
prepare_to_wait_exclusive
(
&
wl
->
fwlog_waitq
,
&
wait
,
TASK_INTERRUPTIBLE
);
if
(
wl
->
fwlog_size
!=
0
)
{
finish_wait
(
&
wl
->
fwlog_waitq
,
&
wait
);
break
;
}
mutex_unlock
(
&
wl
->
mutex
);
schedule
();
finish_wait
(
&
wl
->
fwlog_waitq
,
&
wait
);
if
(
signal_pending
(
current
))
return
-
ERESTARTSYS
;
ret
=
mutex_lock_interruptible
(
&
wl
->
mutex
);
if
(
ret
<
0
)
return
-
ERESTARTSYS
;
}
/* Check if the fwlog is still valid */
if
(
wl
->
fwlog_size
<
0
)
{
mutex_unlock
(
&
wl
->
mutex
);
return
0
;
}
/* Seeking is not supported - old logs are not kept. Disregard pos. */
len
=
min
(
count
,
(
size_t
)
wl
->
fwlog_size
);
wl
->
fwlog_size
-=
len
;
memcpy
(
buffer
,
wl
->
fwlog
,
len
);
/* Make room for new messages */
memmove
(
wl
->
fwlog
,
wl
->
fwlog
+
len
,
wl
->
fwlog_size
);
mutex_unlock
(
&
wl
->
mutex
);
return
len
;
}
static
struct
bin_attribute
fwlog_attr
=
{
.
attr
=
{.
name
=
"fwlog"
,
.
mode
=
S_IRUSR
},
.
read
=
wl1271_sysfs_read_fwlog
,
};
int
wlcore_sysfs_init
(
struct
wl1271
*
wl
)
{
int
ret
;
/* Create sysfs file to control bt coex state */
ret
=
device_create_file
(
wl
->
dev
,
&
dev_attr_bt_coex_state
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to create sysfs file bt_coex_state"
);
goto
out
;
}
/* Create sysfs file to get HW PG version */
ret
=
device_create_file
(
wl
->
dev
,
&
dev_attr_hw_pg_ver
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to create sysfs file hw_pg_ver"
);
goto
out_bt_coex_state
;
}
/* Create sysfs file for the FW log */
ret
=
device_create_bin_file
(
wl
->
dev
,
&
fwlog_attr
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to create sysfs file fwlog"
);
goto
out_hw_pg_ver
;
}
goto
out
;
out_hw_pg_ver:
device_remove_file
(
wl
->
dev
,
&
dev_attr_hw_pg_ver
);
out_bt_coex_state:
device_remove_file
(
wl
->
dev
,
&
dev_attr_bt_coex_state
);
out:
return
ret
;
}
void
wlcore_sysfs_free
(
struct
wl1271
*
wl
)
{
device_remove_bin_file
(
wl
->
dev
,
&
fwlog_attr
);
device_remove_file
(
wl
->
dev
,
&
dev_attr_hw_pg_ver
);
device_remove_file
(
wl
->
dev
,
&
dev_attr_bt_coex_state
);
}
drivers/net/wireless/ti/wlcore/sysfs.h
0 → 100644
View file @
9e49a9d3
/*
* This file is part of wlcore
*
* Copyright (C) 2013 Texas Instruments Inc.
*
* 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
*
*/
#ifndef __SYSFS_H__
#define __SYSFS_H__
int
wlcore_sysfs_init
(
struct
wl1271
*
wl
);
void
wlcore_sysfs_free
(
struct
wl1271
*
wl
);
#endif
drivers/net/wireless/ti/wlcore/tx.c
View file @
9e49a9d3
...
...
@@ -386,7 +386,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
is_wep
=
(
cipher
==
WLAN_CIPHER_SUITE_WEP40
)
||
(
cipher
==
WLAN_CIPHER_SUITE_WEP104
);
if
(
unlikely
(
is_wep
&&
wlvif
->
default_key
!=
idx
))
{
if
(
WARN_ON
(
is_wep
&&
wlvif
->
default_key
!=
idx
))
{
ret
=
wl1271_set_default_wep_key
(
wl
,
wlvif
,
idx
);
if
(
ret
<
0
)
return
ret
;
...
...
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