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
e55034e9
Commit
e55034e9
authored
Apr 25, 2011
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
73b48099
cf27d867
Changes
29
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
1324 additions
and
289 deletions
+1324
-289
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/Kconfig
+1
-1
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+47
-12
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+11
-0
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+236
-43
drivers/net/wireless/wl12xx/boot.h
drivers/net/wireless/wl12xx/boot.h
+52
-0
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+91
-6
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+34
-0
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+6
-11
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+1
-1
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+12
-5
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/event.h
+4
-1
drivers/net/wireless/wl12xx/ini.h
drivers/net/wireless/wl12xx/ini.h
+96
-2
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+40
-5
drivers/net/wireless/wl12xx/init.h
drivers/net/wireless/wl12xx/init.h
+1
-0
drivers/net/wireless/wl12xx/io.c
drivers/net/wireless/wl12xx/io.c
+11
-0
drivers/net/wireless/wl12xx/io.h
drivers/net/wireless/wl12xx/io.h
+3
-0
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+276
-67
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+0
-3
drivers/net/wireless/wl12xx/reg.h
drivers/net/wireless/wl12xx/reg.h
+2
-13
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+24
-20
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.c
+10
-7
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/sdio.c
+24
-3
drivers/net/wireless/wl12xx/sdio_test.c
drivers/net/wireless/wl12xx/sdio_test.c
+17
-3
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/spi.c
+14
-3
drivers/net/wireless/wl12xx/testmode.c
drivers/net/wireless/wl12xx/testmode.c
+5
-1
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+176
-58
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+50
-10
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+56
-9
include/linux/wl12xx.h
include/linux/wl12xx.h
+24
-5
No files found.
drivers/net/wireless/wl12xx/Kconfig
View file @
e55034e9
...
...
@@ -3,7 +3,7 @@ menuconfig WL12XX_MENU
depends on MAC80211 && EXPERIMENTAL
---help---
This will enable TI wl12xx driver support for the following chips:
wl1271
and wl127
3.
wl1271
, wl1273, wl1281 and wl128
3.
The drivers make use of the mac80211 stack.
config WL12XX
...
...
drivers/net/wireless/wl12xx/acx.c
View file @
e55034e9
...
...
@@ -965,10 +965,13 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
}
/* memory config */
mem_conf
->
num_stations
=
wl
->
conf
.
mem
.
num_stations
;
mem_conf
->
rx_mem_block_num
=
wl
->
conf
.
mem
.
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
wl
->
conf
.
mem
.
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
wl
->
conf
.
mem
.
ssid_profiles
;
/* FIXME: for now we always use mem_wl127x for AP, because it
* doesn't support dynamic memory and we don't have the
* optimal values for wl128x without dynamic memory yet */
mem_conf
->
num_stations
=
wl
->
conf
.
mem_wl127x
.
num_stations
;
mem_conf
->
rx_mem_block_num
=
wl
->
conf
.
mem_wl127x
.
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
wl
->
conf
.
mem_wl127x
.
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
wl
->
conf
.
mem_wl127x
.
ssid_profiles
;
mem_conf
->
total_tx_descriptors
=
cpu_to_le32
(
ACX_TX_DESCRIPTORS
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MEM_CFG
,
mem_conf
,
...
...
@@ -986,6 +989,7 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
int
wl1271_acx_sta_mem_cfg
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_sta_config_memory
*
mem_conf
;
struct
conf_memory_settings
*
mem
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"wl1271 mem cfg"
);
...
...
@@ -996,16 +1000,21 @@ int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
goto
out
;
}
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
mem
=
&
wl
->
conf
.
mem_wl128x
;
else
mem
=
&
wl
->
conf
.
mem_wl127x
;
/* memory config */
mem_conf
->
num_stations
=
wl
->
conf
.
mem
.
num_stations
;
mem_conf
->
rx_mem_block_num
=
wl
->
conf
.
mem
.
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
wl
->
conf
.
mem
.
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
wl
->
conf
.
mem
.
ssid_profiles
;
mem_conf
->
num_stations
=
mem
->
num_stations
;
mem_conf
->
rx_mem_block_num
=
mem
->
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
mem
->
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
mem
->
ssid_profiles
;
mem_conf
->
total_tx_descriptors
=
cpu_to_le32
(
ACX_TX_DESCRIPTORS
);
mem_conf
->
dyn_mem_enable
=
wl
->
conf
.
mem
.
dynamic_memory
;
mem_conf
->
tx_free_req
=
wl
->
conf
.
mem
.
min_req_tx_blocks
;
mem_conf
->
rx_free_req
=
wl
->
conf
.
mem
.
min_req_rx_blocks
;
mem_conf
->
tx_min
=
wl
->
conf
.
mem
.
tx_min
;
mem_conf
->
dyn_mem_enable
=
mem
->
dynamic_memory
;
mem_conf
->
tx_free_req
=
mem
->
min_req_tx_blocks
;
mem_conf
->
rx_free_req
=
mem
->
min_req_rx_blocks
;
mem_conf
->
tx_min
=
mem
->
tx_min
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MEM_CFG
,
mem_conf
,
sizeof
(
*
mem_conf
));
...
...
@@ -1019,6 +1028,32 @@ int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
return
ret
;
}
int
wl1271_acx_host_if_cfg_bitmap
(
struct
wl1271
*
wl
,
u32
host_cfg_bitmap
)
{
struct
wl1271_acx_host_config_bitmap
*
bitmap_conf
;
int
ret
;
bitmap_conf
=
kzalloc
(
sizeof
(
*
bitmap_conf
),
GFP_KERNEL
);
if
(
!
bitmap_conf
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
bitmap_conf
->
host_cfg_bitmap
=
cpu_to_le32
(
host_cfg_bitmap
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_HOST_IF_CFG_BITMAP
,
bitmap_conf
,
sizeof
(
*
bitmap_conf
));
if
(
ret
<
0
)
{
wl1271_warning
(
"wl1271 bitmap config opt failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
bitmap_conf
);
return
ret
;
}
int
wl1271_acx_init_mem_config
(
struct
wl1271
*
wl
)
{
int
ret
;
...
...
drivers/net/wireless/wl12xx/acx.h
View file @
e55034e9
...
...
@@ -939,6 +939,16 @@ struct wl1271_acx_keep_alive_config {
u8
padding
;
}
__packed
;
#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1)
#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3)
struct
wl1271_acx_host_config_bitmap
{
struct
acx_header
header
;
__le32
host_cfg_bitmap
;
}
__packed
;
enum
{
WL1271_ACX_TRIG_TYPE_LEVEL
=
0
,
WL1271_ACX_TRIG_TYPE_EDGE
,
...
...
@@ -1275,6 +1285,7 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl);
int
wl1271_acx_ap_mem_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_mem_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_init_mem_config
(
struct
wl1271
*
wl
);
int
wl1271_acx_host_if_cfg_bitmap
(
struct
wl1271
*
wl
,
u32
host_cfg_bitmap
);
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
);
...
...
drivers/net/wireless/wl12xx/boot.c
View file @
e55034e9
...
...
@@ -22,6 +22,7 @@
*/
#include <linux/slab.h>
#include <linux/wl12xx.h>
#include "acx.h"
#include "reg.h"
...
...
@@ -243,16 +244,39 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
if
(
wl
->
nvs
==
NULL
)
return
-
ENODEV
;
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
{
struct
wl128x_nvs_file
*
nvs
=
(
struct
wl128x_nvs_file
*
)
wl
->
nvs
;
if
(
wl
->
nvs_len
==
sizeof
(
struct
wl128x_nvs_file
))
{
if
(
nvs
->
general_params
.
dual_mode_select
)
wl
->
enable_11a
=
true
;
}
else
{
wl1271_error
(
"nvs size is not as expected: %zu != %zu"
,
wl
->
nvs_len
,
sizeof
(
struct
wl128x_nvs_file
));
kfree
(
wl
->
nvs
);
wl
->
nvs
=
NULL
;
wl
->
nvs_len
=
0
;
return
-
EILSEQ
;
}
/* only the first part of the NVS needs to be uploaded */
nvs_len
=
sizeof
(
nvs
->
nvs
);
nvs_ptr
=
(
u8
*
)
nvs
->
nvs
;
}
else
{
struct
wl1271_nvs_file
*
nvs
=
(
struct
wl1271_nvs_file
*
)
wl
->
nvs
;
/*
* FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
* configurations) can be removed when those NVS files stop floating
*
around.
* FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
* band configurations) can be removed when those NVS files stop
* floating
around.
*/
if
(
wl
->
nvs_len
==
sizeof
(
struct
wl1271_nvs_file
)
||
wl
->
nvs_len
==
WL1271_INI_LEGACY_NVS_FILE_SIZE
)
{
/* for now 11a is unsupported in AP mode */
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
&&
wl
->
nvs
->
general_params
.
dual_mode_select
)
nvs
->
general_params
.
dual_mode_select
)
wl
->
enable_11a
=
true
;
}
...
...
@@ -268,8 +292,9 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
}
/* only the first part of the NVS needs to be uploaded */
nvs_len
=
sizeof
(
wl
->
nvs
->
nvs
);
nvs_ptr
=
(
u8
*
)
wl
->
nvs
->
nvs
;
nvs_len
=
sizeof
(
nvs
->
nvs
);
nvs_ptr
=
(
u8
*
)
nvs
->
nvs
;
}
/* update current MAC address to NVS */
nvs_ptr
[
11
]
=
wl
->
mac_addr
[
0
];
...
...
@@ -319,10 +344,13 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
/*
* We've reached the first zero length, the first NVS table
* is located at an aligned offset which is at least 7 bytes further.
* NOTE: The wl->nvs->nvs element must be first, in order to
* simplify the casting, we assume it is at the beginning of
* the wl->nvs structure.
*/
nvs_ptr
=
(
u8
*
)
wl
->
nvs
->
nvs
+
ALIGN
(
nvs_ptr
-
(
u8
*
)
wl
->
nvs
->
nvs
+
7
,
4
);
nvs_len
-=
nvs_ptr
-
(
u8
*
)
wl
->
nvs
->
nvs
;
nvs_ptr
=
(
u8
*
)
wl
->
nvs
+
ALIGN
(
nvs_ptr
-
(
u8
*
)
wl
->
nvs
+
7
,
4
);
nvs_len
-=
nvs_ptr
-
(
u8
*
)
wl
->
nvs
;
/* Now we must set the partition correctly */
wl1271_set_partition
(
wl
,
&
part_table
[
PART_WORK
]);
...
...
@@ -454,6 +482,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
;
else
wl
->
event_mask
|=
DUMMY_PACKET_EVENT_ID
;
ret
=
wl1271_event_unmask
(
wl
);
if
(
ret
<
0
)
{
...
...
@@ -493,24 +523,159 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
}
/* uploads NVS and firmware */
int
wl1271_load_firmware
(
struct
wl1271
*
wl
)
static
int
wl128x_switch_tcxo_to_fref
(
struct
wl1271
*
wl
)
{
int
ret
=
0
;
u32
tmp
,
clk
,
pause
;
u16
spare_reg
;
/* Mask bits [2] & [8:4] in the sys_clk_cfg register */
spare_reg
=
wl1271_top_reg_read
(
wl
,
WL_SPARE_REG
);
if
(
spare_reg
==
0xFFFF
)
return
-
EFAULT
;
spare_reg
|=
(
BIT
(
3
)
|
BIT
(
5
)
|
BIT
(
6
));
wl1271_top_reg_write
(
wl
,
WL_SPARE_REG
,
spare_reg
);
/* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
wl1271_top_reg_write
(
wl
,
SYS_CLK_CFG_REG
,
WL_CLK_REQ_TYPE_PG2
|
MCS_PLL_CLK_SEL_FREF
);
/* Delay execution for 15msec, to let the HW settle */
mdelay
(
15
);
return
0
;
}
static
bool
wl128x_is_tcxo_valid
(
struct
wl1271
*
wl
)
{
u16
tcxo_detection
;
tcxo_detection
=
wl1271_top_reg_read
(
wl
,
TCXO_CLK_DETECT_REG
);
if
(
tcxo_detection
&
TCXO_DET_FAILED
)
return
false
;
return
true
;
}
static
bool
wl128x_is_fref_valid
(
struct
wl1271
*
wl
)
{
u16
fref_detection
;
fref_detection
=
wl1271_top_reg_read
(
wl
,
FREF_CLK_DETECT_REG
);
if
(
fref_detection
&
FREF_CLK_DETECT_FAIL
)
return
false
;
return
true
;
}
static
int
wl128x_manually_configure_mcs_pll
(
struct
wl1271
*
wl
)
{
wl1271_top_reg_write
(
wl
,
MCS_PLL_M_REG
,
MCS_PLL_M_REG_VAL
);
wl1271_top_reg_write
(
wl
,
MCS_PLL_N_REG
,
MCS_PLL_N_REG_VAL
);
wl1271_top_reg_write
(
wl
,
MCS_PLL_CONFIG_REG
,
MCS_PLL_CONFIG_REG_VAL
);
return
0
;
}
static
int
wl128x_configure_mcs_pll
(
struct
wl1271
*
wl
,
int
clk
)
{
u16
spare_reg
;
u16
pll_config
;
u8
input_freq
;
/* Mask bits [3:1] in the sys_clk_cfg register */
spare_reg
=
wl1271_top_reg_read
(
wl
,
WL_SPARE_REG
);
if
(
spare_reg
==
0xFFFF
)
return
-
EFAULT
;
spare_reg
|=
BIT
(
2
);
wl1271_top_reg_write
(
wl
,
WL_SPARE_REG
,
spare_reg
);
/* Handle special cases of the TCXO clock */
if
(
wl
->
tcxo_clock
==
WL12XX_TCXOCLOCK_16_8
||
wl
->
tcxo_clock
==
WL12XX_TCXOCLOCK_33_6
)
return
wl128x_manually_configure_mcs_pll
(
wl
);
/* Set the input frequency according to the selected clock source */
input_freq
=
(
clk
&
1
)
+
1
;
pll_config
=
wl1271_top_reg_read
(
wl
,
MCS_PLL_CONFIG_REG
);
if
(
pll_config
==
0xFFFF
)
return
-
EFAULT
;
pll_config
|=
(
input_freq
<<
MCS_SEL_IN_FREQ_SHIFT
);
pll_config
|=
MCS_PLL_ENABLE_HP
;
wl1271_top_reg_write
(
wl
,
MCS_PLL_CONFIG_REG
,
pll_config
);
return
0
;
}
/*
* WL128x has two clocks input - TCXO and FREF.
* TCXO is the main clock of the device, while FREF is used to sync
* between the GPS and the cellular modem.
* In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
* as the WLAN/BT main clock.
*/
static
int
wl128x_boot_clk
(
struct
wl1271
*
wl
,
int
*
selected_clock
)
{
u16
sys_clk_cfg
;
/* For XTAL-only modes, FREF will be used after switching from TCXO */
if
(
wl
->
ref_clock
==
WL12XX_REFCLOCK_26_XTAL
||
wl
->
ref_clock
==
WL12XX_REFCLOCK_38_XTAL
)
{
if
(
!
wl128x_switch_tcxo_to_fref
(
wl
))
return
-
EINVAL
;
goto
fref_clk
;
}
/* Query the HW, to determine which clock source we should use */
sys_clk_cfg
=
wl1271_top_reg_read
(
wl
,
SYS_CLK_CFG_REG
);
if
(
sys_clk_cfg
==
0xFFFF
)
return
-
EINVAL
;
if
(
sys_clk_cfg
&
PRCM_CM_EN_MUX_WLAN_FREF
)
goto
fref_clk
;
/* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
if
(
wl
->
tcxo_clock
==
WL12XX_TCXOCLOCK_16_368
||
wl
->
tcxo_clock
==
WL12XX_TCXOCLOCK_32_736
)
{
if
(
!
wl128x_switch_tcxo_to_fref
(
wl
))
return
-
EINVAL
;
goto
fref_clk
;
}
/* TCXO clock is selected */
if
(
!
wl128x_is_tcxo_valid
(
wl
))
return
-
EINVAL
;
*
selected_clock
=
wl
->
tcxo_clock
;
goto
config_mcs_pll
;
fref_clk:
/* FREF clock is selected */
if
(
!
wl128x_is_fref_valid
(
wl
))
return
-
EINVAL
;
*
selected_clock
=
wl
->
ref_clock
;
config_mcs_pll:
return
wl128x_configure_mcs_pll
(
wl
,
*
selected_clock
);
}
static
int
wl127x_boot_clk
(
struct
wl1271
*
wl
)
{
u32
pause
;
u32
clk
;
wl1271_boot_hw_version
(
wl
);
if
(
wl
->
ref_clock
==
0
||
wl
->
ref_clock
==
2
||
wl
->
ref_clock
==
4
)
if
(
wl
->
ref_clock
==
CONF_REF_CLK_19_2_E
||
wl
->
ref_clock
==
CONF_REF_CLK_38_4_E
||
wl
->
ref_clock
==
CONF_REF_CLK_38_4_M_XTAL
)
/* ref clk: 19.2/38.4/38.4-XTAL */
clk
=
0x3
;
else
if
(
wl
->
ref_clock
==
1
||
wl
->
ref_clock
==
3
)
else
if
(
wl
->
ref_clock
==
CONF_REF_CLK_26_E
||
wl
->
ref_clock
==
CONF_REF_CLK_52_E
)
/* ref clk: 26/52 */
clk
=
0x5
;
else
return
-
EINVAL
;
if
(
wl
->
ref_clock
!=
0
)
{
if
(
wl
->
ref_clock
!=
CONF_REF_CLK_19_2_E
)
{
u16
val
;
/* Set clock type (open drain) */
val
=
wl1271_top_reg_read
(
wl
,
OCP_REG_CLK_TYPE
);
...
...
@@ -540,6 +705,26 @@ int wl1271_load_firmware(struct wl1271 *wl)
pause
|=
WU_COUNTER_PAUSE_VAL
;
wl1271_write32
(
wl
,
WU_COUNTER_PAUSE
,
pause
);
return
0
;
}
/* uploads NVS and firmware */
int
wl1271_load_firmware
(
struct
wl1271
*
wl
)
{
int
ret
=
0
;
u32
tmp
,
clk
;
int
selected_clock
=
-
1
;
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
{
ret
=
wl128x_boot_clk
(
wl
,
&
selected_clock
);
if
(
ret
<
0
)
goto
out
;
}
else
{
ret
=
wl127x_boot_clk
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
/* Continue the ELP wake up sequence */
wl1271_write32
(
wl
,
WELP_ARM_COMMAND
,
WELP_ARM_COMMAND_VAL
);
udelay
(
500
);
...
...
@@ -555,7 +740,12 @@ int wl1271_load_firmware(struct wl1271 *wl)
wl1271_debug
(
DEBUG_BOOT
,
"clk2 0x%x"
,
clk
);
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
{
clk
|=
((
selected_clock
&
0x3
)
<<
1
)
<<
4
;
}
else
{
clk
|=
(
wl
->
ref_clock
<<
1
)
<<
4
;
}
wl1271_write32
(
wl
,
DRPW_SCRATCH_START
,
clk
);
wl1271_set_partition
(
wl
,
&
part_table
[
PART_WORK
]);
...
...
@@ -585,16 +775,12 @@ int wl1271_load_firmware(struct wl1271 *wl)
/* 6. read the EEPROM parameters */
tmp
=
wl1271_read32
(
wl
,
SCR_PAD2
);
ret
=
wl1271_boot_write_irq_polarity
(
wl
);
if
(
ret
<
0
)
goto
out
;
wl1271_write32
(
wl
,
ACX_REG_INTERRUPT_MASK
,
WL1271_ACX_ALL_EVENTS_VECTOR
);
/* WL1271: The reference driver skips steps 7 to 10 (jumps directly
* to upload_fw) */
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
wl1271_top_reg_write
(
wl
,
SDIO_IO_DS
,
wl
->
conf
.
hci_io_ds
);
ret
=
wl1271_boot_upload_firmware
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -618,6 +804,13 @@ int wl1271_boot(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_boot_write_irq_polarity
(
wl
);
if
(
ret
<
0
)
goto
out
;
wl1271_write32
(
wl
,
ACX_REG_INTERRUPT_MASK
,
WL1271_ACX_ALL_EVENTS_VECTOR
);
/* Enable firmware interrupts now */
wl1271_boot_enable_interrupts
(
wl
);
...
...
drivers/net/wireless/wl12xx/boot.h
View file @
e55034e9
...
...
@@ -74,4 +74,56 @@ struct wl1271_static_data {
#define FREF_CLK_POLARITY_BITS 0xfffff8ff
#define CLK_REQ_OUTN_SEL 0x700
/* PLL configuration algorithm for wl128x */
#define SYS_CLK_CFG_REG 0x2200
/* Bit[0] - 0-TCXO, 1-FREF */
#define MCS_PLL_CLK_SEL_FREF BIT(0)
/* Bit[3:2] - 01-TCXO, 10-FREF */
#define WL_CLK_REQ_TYPE_FREF BIT(3)
#define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2))
/* Bit[4] - 0-TCXO, 1-FREF */
#define PRCM_CM_EN_MUX_WLAN_FREF BIT(4)
#define TCXO_ILOAD_INT_REG 0x2264
#define TCXO_CLK_DETECT_REG 0x2266
#define TCXO_DET_FAILED BIT(4)
#define FREF_ILOAD_INT_REG 0x2084
#define FREF_CLK_DETECT_REG 0x2086
#define FREF_CLK_DETECT_FAIL BIT(4)
/* Use this reg for masking during driver access */
#define WL_SPARE_REG 0x2320
#define WL_SPARE_VAL BIT(2)
/* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */
#define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3))
#define PLL_LOCK_COUNTERS_REG 0xD8C
#define PLL_LOCK_COUNTERS_COEX 0x0F
#define PLL_LOCK_COUNTERS_MCS 0xF0
#define MCS_PLL_OVERRIDE_REG 0xD90
#define MCS_PLL_CONFIG_REG 0xD92
#define MCS_SEL_IN_FREQ_MASK 0x0070
#define MCS_SEL_IN_FREQ_SHIFT 4
#define MCS_PLL_CONFIG_REG_VAL 0x73
#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1))
#define MCS_PLL_M_REG 0xD94
#define MCS_PLL_N_REG 0xD96
#define MCS_PLL_M_REG_VAL 0xC8
#define MCS_PLL_N_REG_VAL 0x07
#define SDIO_IO_DS 0xd14
/* SDIO/wSPI DS configuration values */
enum
{
HCI_IO_DS_8MA
=
0
,
HCI_IO_DS_4MA
=
1
,
/* default */
HCI_IO_DS_6MA
=
2
,
HCI_IO_DS_2MA
=
3
,
};
/* end PLL configuration algorithm for wl128x */
#endif
drivers/net/wireless/wl12xx/cmd.c
View file @
e55034e9
...
...
@@ -110,7 +110,47 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
int
wl1271_cmd_general_parms
(
struct
wl1271
*
wl
)
{
struct
wl1271_general_parms_cmd
*
gen_parms
;
struct
wl1271_ini_general_params
*
gp
=
&
wl
->
nvs
->
general_params
;
struct
wl1271_ini_general_params
*
gp
=
&
((
struct
wl1271_nvs_file
*
)
wl
->
nvs
)
->
general_params
;
bool
answer
=
false
;
int
ret
;
if
(
!
wl
->
nvs
)
return
-
ENODEV
;
gen_parms
=
kzalloc
(
sizeof
(
*
gen_parms
),
GFP_KERNEL
);
if
(
!
gen_parms
)
return
-
ENOMEM
;
gen_parms
->
test
.
id
=
TEST_CMD_INI_FILE_GENERAL_PARAM
;
memcpy
(
&
gen_parms
->
general_params
,
gp
,
sizeof
(
*
gp
));
if
(
gp
->
tx_bip_fem_auto_detect
)
answer
=
true
;
ret
=
wl1271_cmd_test
(
wl
,
gen_parms
,
sizeof
(
*
gen_parms
),
answer
);
if
(
ret
<
0
)
{
wl1271_warning
(
"CMD_INI_FILE_GENERAL_PARAM failed"
);
goto
out
;
}
gp
->
tx_bip_fem_manufacturer
=
gen_parms
->
general_params
.
tx_bip_fem_manufacturer
;
wl1271_debug
(
DEBUG_CMD
,
"FEM autodetect: %s, manufacturer: %d
\n
"
,
answer
?
"auto"
:
"manual"
,
gp
->
tx_bip_fem_manufacturer
);
out:
kfree
(
gen_parms
);
return
ret
;
}
int
wl128x_cmd_general_parms
(
struct
wl1271
*
wl
)
{
struct
wl128x_general_parms_cmd
*
gen_parms
;
struct
wl128x_ini_general_params
*
gp
=
&
((
struct
wl128x_nvs_file
*
)
wl
->
nvs
)
->
general_params
;
bool
answer
=
false
;
int
ret
;
...
...
@@ -147,8 +187,9 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
int
wl1271_cmd_radio_parms
(
struct
wl1271
*
wl
)
{
struct
wl1271_nvs_file
*
nvs
=
(
struct
wl1271_nvs_file
*
)
wl
->
nvs
;
struct
wl1271_radio_parms_cmd
*
radio_parms
;
struct
wl1271_ini_general_params
*
gp
=
&
wl
->
nvs
->
general_params
;
struct
wl1271_ini_general_params
*
gp
=
&
nvs
->
general_params
;
int
ret
;
if
(
!
wl
->
nvs
)
...
...
@@ -161,18 +202,18 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
radio_parms
->
test
.
id
=
TEST_CMD_INI_FILE_RADIO_PARAM
;
/* 2.4GHz parameters */
memcpy
(
&
radio_parms
->
static_params_2
,
&
wl
->
nvs
->
stat_radio_params_2
,
memcpy
(
&
radio_parms
->
static_params_2
,
&
nvs
->
stat_radio_params_2
,
sizeof
(
struct
wl1271_ini_band_params_2
));
memcpy
(
&
radio_parms
->
dyn_params_2
,
&
wl
->
nvs
->
dyn_radio_params_2
[
gp
->
tx_bip_fem_manufacturer
].
params
,
&
nvs
->
dyn_radio_params_2
[
gp
->
tx_bip_fem_manufacturer
].
params
,
sizeof
(
struct
wl1271_ini_fem_params_2
));
/* 5GHz parameters */
memcpy
(
&
radio_parms
->
static_params_5
,
&
wl
->
nvs
->
stat_radio_params_5
,
&
nvs
->
stat_radio_params_5
,
sizeof
(
struct
wl1271_ini_band_params_5
));
memcpy
(
&
radio_parms
->
dyn_params_5
,
&
wl
->
nvs
->
dyn_radio_params_5
[
gp
->
tx_bip_fem_manufacturer
].
params
,
&
nvs
->
dyn_radio_params_5
[
gp
->
tx_bip_fem_manufacturer
].
params
,
sizeof
(
struct
wl1271_ini_fem_params_5
));
wl1271_dump
(
DEBUG_CMD
,
"TEST_CMD_INI_FILE_RADIO_PARAM: "
,
...
...
@@ -186,6 +227,50 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
return
ret
;
}
int
wl128x_cmd_radio_parms
(
struct
wl1271
*
wl
)
{
struct
wl128x_nvs_file
*
nvs
=
(
struct
wl128x_nvs_file
*
)
wl
->
nvs
;
struct
wl128x_radio_parms_cmd
*
radio_parms
;
struct
wl128x_ini_general_params
*
gp
=
&
nvs
->
general_params
;
int
ret
;
if
(
!
wl
->
nvs
)
return
-
ENODEV
;
radio_parms
=
kzalloc
(
sizeof
(
*
radio_parms
),
GFP_KERNEL
);
if
(
!
radio_parms
)
return
-
ENOMEM
;
radio_parms
->
test
.
id
=
TEST_CMD_INI_FILE_RADIO_PARAM
;
/* 2.4GHz parameters */
memcpy
(
&
radio_parms
->
static_params_2
,
&
nvs
->
stat_radio_params_2
,
sizeof
(
struct
wl128x_ini_band_params_2
));
memcpy
(
&
radio_parms
->
dyn_params_2
,
&
nvs
->
dyn_radio_params_2
[
gp
->
tx_bip_fem_manufacturer
].
params
,
sizeof
(
struct
wl128x_ini_fem_params_2
));
/* 5GHz parameters */
memcpy
(
&
radio_parms
->
static_params_5
,
&
nvs
->
stat_radio_params_5
,
sizeof
(
struct
wl128x_ini_band_params_5
));
memcpy
(
&
radio_parms
->
dyn_params_5
,
&
nvs
->
dyn_radio_params_5
[
gp
->
tx_bip_fem_manufacturer
].
params
,
sizeof
(
struct
wl128x_ini_fem_params_5
));
radio_parms
->
fem_vendor_and_options
=
nvs
->
fem_vendor_and_options
;
wl1271_dump
(
DEBUG_CMD
,
"TEST_CMD_INI_FILE_RADIO_PARAM: "
,
radio_parms
,
sizeof
(
*
radio_parms
));
ret
=
wl1271_cmd_test
(
wl
,
radio_parms
,
sizeof
(
*
radio_parms
),
0
);
if
(
ret
<
0
)
wl1271_warning
(
"CMD_INI_FILE_RADIO_PARAM failed"
);
kfree
(
radio_parms
);
return
ret
;
}
int
wl1271_cmd_ext_radio_parms
(
struct
wl1271
*
wl
)
{
struct
wl1271_ext_radio_parms_cmd
*
ext_radio_parms
;
...
...
drivers/net/wireless/wl12xx/cmd.h
View file @
e55034e9
...
...
@@ -32,7 +32,9 @@ struct acx_header;
int
wl1271_cmd_send
(
struct
wl1271
*
wl
,
u16
id
,
void
*
buf
,
size_t
len
,
size_t
res_len
);
int
wl1271_cmd_general_parms
(
struct
wl1271
*
wl
);
int
wl128x_cmd_general_parms
(
struct
wl1271
*
wl
);
int
wl1271_cmd_radio_parms
(
struct
wl1271
*
wl
);
int
wl128x_cmd_radio_parms
(
struct
wl1271
*
wl
);
int
wl1271_cmd_ext_radio_parms
(
struct
wl1271
*
wl
);
int
wl1271_cmd_join
(
struct
wl1271
*
wl
,
u8
bss_type
);
int
wl1271_cmd_test
(
struct
wl1271
*
wl
,
void
*
buf
,
size_t
buf_len
,
u8
answer
);
...
...
@@ -415,6 +417,21 @@ struct wl1271_general_parms_cmd {
u8
padding
[
3
];
}
__packed
;
struct
wl128x_general_parms_cmd
{
struct
wl1271_cmd_header
header
;
struct
wl1271_cmd_test_header
test
;
struct
wl128x_ini_general_params
general_params
;
u8
sr_debug_table
[
WL1271_INI_MAX_SMART_REFLEX_PARAM
];
u8
sr_sen_n_p
;
u8
sr_sen_n_p_gain
;
u8
sr_sen_nrn
;
u8
sr_sen_prn
;
u8
padding
[
3
];
}
__packed
;
struct
wl1271_radio_parms_cmd
{
struct
wl1271_cmd_header
header
;
...
...
@@ -431,6 +448,23 @@ struct wl1271_radio_parms_cmd {
u8
padding3
[
2
];
}
__packed
;
struct
wl128x_radio_parms_cmd
{
struct
wl1271_cmd_header
header
;
struct
wl1271_cmd_test_header
test
;
/* Static radio parameters */
struct
wl128x_ini_band_params_2
static_params_2
;
struct
wl128x_ini_band_params_5
static_params_5
;
u8
fem_vendor_and_options
;
/* Dynamic radio parameters */
struct
wl128x_ini_fem_params_2
dyn_params_2
;
u8
padding2
;
struct
wl128x_ini_fem_params_5
dyn_params_5
;
}
__packed
;
struct
wl1271_ext_radio_parms_cmd
{
struct
wl1271_cmd_header
header
;
...
...
drivers/net/wireless/wl12xx/conf.h
View file @
e55034e9
...
...
@@ -1004,7 +1004,9 @@ enum {
CONF_REF_CLK_19_2_E
,
CONF_REF_CLK_26_E
,
CONF_REF_CLK_38_4_E
,
CONF_REF_CLK_52_E
CONF_REF_CLK_52_E
,
CONF_REF_CLK_38_4_M_XTAL
,
CONF_REF_CLK_26_M_XTAL
,
};
enum
single_dual_band_enum
{
...
...
@@ -1018,15 +1020,6 @@ enum single_dual_band_enum {
#define CONF_NUMBER_OF_CHANNELS_2_4 14
#define CONF_NUMBER_OF_CHANNELS_5 35
struct
conf_radio_parms
{
/*
* FEM parameter set to use
*
* Range: 0 or 1
*/
u8
fem
;
};
struct
conf_itrim_settings
{
/* enable dco itrim */
u8
enable
;
...
...
@@ -1202,7 +1195,9 @@ struct conf_drv_settings {
struct
conf_scan_settings
scan
;
struct
conf_rf_settings
rf
;
struct
conf_ht_setting
ht
;
struct
conf_memory_settings
mem
;
struct
conf_memory_settings
mem_wl127x
;
struct
conf_memory_settings
mem_wl128x
;
u8
hci_io_ds
;
};
#endif
drivers/net/wireless/wl12xx/debugfs.c
View file @
e55034e9
...
...
@@ -267,7 +267,7 @@ static ssize_t gpio_power_write(struct file *file,
}
buf
[
len
]
=
'\0'
;
ret
=
strict_
strtoul
(
buf
,
0
,
&
value
);
ret
=
k
strtoul
(
buf
,
0
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in gpio_power"
);
return
-
EINVAL
;
...
...
drivers/net/wireless/wl12xx/event.c
View file @
e55034e9
...
...
@@ -33,6 +33,7 @@ void wl1271_pspoll_work(struct work_struct *work)
{
struct
delayed_work
*
dwork
;
struct
wl1271
*
wl
;
int
ret
;
dwork
=
container_of
(
work
,
struct
delayed_work
,
work
);
wl
=
container_of
(
dwork
,
struct
wl1271
,
pspoll_work
);
...
...
@@ -55,8 +56,13 @@ void wl1271_pspoll_work(struct work_struct *work)
* delivery failure occurred, and no-one changed state since, so
* we should go back to powersave.
*/
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
wl1271_ps_set_mode
(
wl
,
STATION_POWER_SAVE_MODE
,
wl
->
basic_rate
,
true
);
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
};
...
...
@@ -129,11 +135,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
/* enable beacon early termination */
ret
=
wl1271_acx_bet_enable
(
wl
,
true
);
if
(
ret
<
0
)
break
;
/* go to extremely low power mode */
wl1271_ps_elp_sleep
(
wl
);
break
;
default:
break
;
...
...
@@ -228,6 +229,12 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_event_rssi_trigger
(
wl
,
mbox
);
}
if
((
vector
&
DUMMY_PACKET_EVENT_ID
)
&&
!
is_ap
)
{
wl1271_debug
(
DEBUG_EVENT
,
"DUMMY_PACKET_ID_EVENT_ID"
);
if
(
wl
->
vif
)
wl1271_tx_dummy_packet
(
wl
);
}
if
(
wl
->
vif
&&
beacon_loss
)
ieee80211_connection_loss
(
wl
->
vif
);
...
...
drivers/net/wireless/wl12xx/event.h
View file @
e55034e9
...
...
@@ -59,7 +59,10 @@ enum {
BSS_LOSE_EVENT_ID
=
BIT
(
18
),
REGAINED_BSS_EVENT_ID
=
BIT
(
19
),
ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID
=
BIT
(
20
),
STA_REMOVE_COMPLETE_EVENT_ID
=
BIT
(
21
),
/* AP */
/* STA: dummy paket for dynamic mem blocks */
DUMMY_PACKET_EVENT_ID
=
BIT
(
21
),
/* AP: STA remove complete */
STA_REMOVE_COMPLETE_EVENT_ID
=
BIT
(
21
),
SOFT_GEMINI_SENSE_EVENT_ID
=
BIT
(
22
),
SOFT_GEMINI_PREDICTION_EVENT_ID
=
BIT
(
23
),
SOFT_GEMINI_AVALANCHE_EVENT_ID
=
BIT
(
24
),
...
...
drivers/net/wireless/wl12xx/ini.h
View file @
e55034e9
...
...
@@ -41,6 +41,28 @@ struct wl1271_ini_general_params {
u8
srf3
[
WL1271_INI_MAX_SMART_REFLEX_PARAM
];
}
__packed
;
#define WL128X_INI_MAX_SETTINGS_PARAM 4
struct
wl128x_ini_general_params
{
u8
ref_clock
;
u8
settling_time
;
u8
clk_valid_on_wakeup
;
u8
tcxo_ref_clock
;
u8
tcxo_settling_time
;
u8
tcxo_valid_on_wakeup
;
u8
tcxo_ldo_voltage
;
u8
xtal_itrim_val
;
u8
platform_conf
;
u8
dual_mode_select
;
u8
tx_bip_fem_auto_detect
;
u8
tx_bip_fem_manufacturer
;
u8
general_settings
[
WL128X_INI_MAX_SETTINGS_PARAM
];
u8
sr_state
;
u8
srf1
[
WL1271_INI_MAX_SMART_REFLEX_PARAM
];
u8
srf2
[
WL1271_INI_MAX_SMART_REFLEX_PARAM
];
u8
srf3
[
WL1271_INI_MAX_SMART_REFLEX_PARAM
];
}
__packed
;
#define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15
struct
wl1271_ini_band_params_2
{
...
...
@@ -49,9 +71,16 @@ struct wl1271_ini_band_params_2 {
u8
rx_rssi_process_compens
[
WL1271_INI_RSSI_PROCESS_COMPENS_SIZE
];
}
__packed
;
#define WL1271_INI_RATE_GROUP_COUNT 6
#define WL1271_INI_CHANNEL_COUNT_2 14
struct
wl128x_ini_band_params_2
{
u8
rx_trace_insertion_loss
;
u8
tx_trace_loss
[
WL1271_INI_CHANNEL_COUNT_2
];
u8
rx_rssi_process_compens
[
WL1271_INI_RSSI_PROCESS_COMPENS_SIZE
];
}
__packed
;
#define WL1271_INI_RATE_GROUP_COUNT 6
struct
wl1271_ini_fem_params_2
{
__le16
tx_bip_ref_pd_voltage
;
u8
tx_bip_ref_power
;
...
...
@@ -68,6 +97,28 @@ struct wl1271_ini_fem_params_2 {
u8
normal_to_degraded_high_thr
;
}
__packed
;
#define WL128X_INI_RATE_GROUP_COUNT 7
/* low and high temperatures */
#define WL128X_INI_PD_VS_TEMPERATURE_RANGES 2
struct
wl128x_ini_fem_params_2
{
__le16
tx_bip_ref_pd_voltage
;
u8
tx_bip_ref_power
;
u8
tx_bip_ref_offset
;
u8
tx_per_rate_pwr_limits_normal
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_per_rate_pwr_limits_degraded
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_per_rate_pwr_limits_extreme
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_per_chan_pwr_limits_11b
[
WL1271_INI_CHANNEL_COUNT_2
];
u8
tx_per_chan_pwr_limits_ofdm
[
WL1271_INI_CHANNEL_COUNT_2
];
u8
tx_pd_vs_rate_offsets
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_ibias
[
WL128X_INI_RATE_GROUP_COUNT
+
1
];
u8
tx_pd_vs_chan_offsets
[
WL1271_INI_CHANNEL_COUNT_2
];
u8
tx_pd_vs_temperature
[
WL128X_INI_PD_VS_TEMPERATURE_RANGES
];
u8
rx_fem_insertion_loss
;
u8
degraded_low_to_normal_thr
;
u8
normal_to_degraded_high_thr
;
}
__packed
;
#define WL1271_INI_CHANNEL_COUNT_5 35
#define WL1271_INI_SUB_BAND_COUNT_5 7
...
...
@@ -77,6 +128,12 @@ struct wl1271_ini_band_params_5 {
u8
rx_rssi_process_compens
[
WL1271_INI_RSSI_PROCESS_COMPENS_SIZE
];
}
__packed
;
struct
wl128x_ini_band_params_5
{
u8
rx_trace_insertion_loss
[
WL1271_INI_SUB_BAND_COUNT_5
];
u8
tx_trace_loss
[
WL1271_INI_CHANNEL_COUNT_5
];
u8
rx_rssi_process_compens
[
WL1271_INI_RSSI_PROCESS_COMPENS_SIZE
];
}
__packed
;
struct
wl1271_ini_fem_params_5
{
__le16
tx_bip_ref_pd_voltage
[
WL1271_INI_SUB_BAND_COUNT_5
];
u8
tx_bip_ref_power
[
WL1271_INI_SUB_BAND_COUNT_5
];
...
...
@@ -92,6 +149,23 @@ struct wl1271_ini_fem_params_5 {
u8
normal_to_degraded_high_thr
;
}
__packed
;
struct
wl128x_ini_fem_params_5
{
__le16
tx_bip_ref_pd_voltage
[
WL1271_INI_SUB_BAND_COUNT_5
];
u8
tx_bip_ref_power
[
WL1271_INI_SUB_BAND_COUNT_5
];
u8
tx_bip_ref_offset
[
WL1271_INI_SUB_BAND_COUNT_5
];
u8
tx_per_rate_pwr_limits_normal
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_per_rate_pwr_limits_degraded
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_per_rate_pwr_limits_extreme
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_per_chan_pwr_limits_ofdm
[
WL1271_INI_CHANNEL_COUNT_5
];
u8
tx_pd_vs_rate_offsets
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_ibias
[
WL128X_INI_RATE_GROUP_COUNT
];
u8
tx_pd_vs_chan_offsets
[
WL1271_INI_CHANNEL_COUNT_5
];
u8
tx_pd_vs_temperature
[
WL1271_INI_SUB_BAND_COUNT_5
*
WL128X_INI_PD_VS_TEMPERATURE_RANGES
];
u8
rx_fem_insertion_loss
[
WL1271_INI_SUB_BAND_COUNT_5
];
u8
degraded_low_to_normal_thr
;
u8
normal_to_degraded_high_thr
;
}
__packed
;
/* NVS data structure */
#define WL1271_INI_NVS_SECTION_SIZE 468
...
...
@@ -100,7 +174,7 @@ struct wl1271_ini_fem_params_5 {
#define WL1271_INI_LEGACY_NVS_FILE_SIZE 800
struct
wl1271_nvs_file
{
/* NVS section */
/* NVS section
- must be first!
*/
u8
nvs
[
WL1271_INI_NVS_SECTION_SIZE
];
/* INI section */
...
...
@@ -120,4 +194,24 @@ struct wl1271_nvs_file {
}
dyn_radio_params_5
[
WL1271_INI_FEM_MODULE_COUNT
];
}
__packed
;
struct
wl128x_nvs_file
{
/* NVS section - must be first! */
u8
nvs
[
WL1271_INI_NVS_SECTION_SIZE
];
/* INI section */
struct
wl128x_ini_general_params
general_params
;
u8
fem_vendor_and_options
;
struct
wl128x_ini_band_params_2
stat_radio_params_2
;
u8
padding2
;
struct
{
struct
wl128x_ini_fem_params_2
params
;
u8
padding
;
}
dyn_radio_params_2
[
WL1271_INI_FEM_MODULE_COUNT
];
struct
wl128x_ini_band_params_5
stat_radio_params_5
;
u8
padding3
;
struct
{
struct
wl128x_ini_fem_params_5
params
;
u8
padding
;
}
dyn_radio_params_5
[
WL1271_INI_FEM_MODULE_COUNT
];
}
__packed
;
#endif
drivers/net/wireless/wl12xx/init.c
View file @
e55034e9
...
...
@@ -31,6 +31,7 @@
#include "cmd.h"
#include "reg.h"
#include "tx.h"
#include "io.h"
int
wl1271_sta_init_templates_config
(
struct
wl1271
*
wl
)
{
...
...
@@ -321,9 +322,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
{
int
ret
;
if
(
wl
->
chip
.
id
!=
CHIP_ID_1283_PG20
)
{
ret
=
wl1271_cmd_ext_radio_parms
(
wl
);
if
(
ret
<
0
)
return
ret
;
}
/* PS config */
ret
=
wl1271_acx_config_ps
(
wl
);
...
...
@@ -504,6 +507,27 @@ static int wl1271_set_ba_policies(struct wl1271 *wl)
return
ret
;
}
int
wl1271_chip_specific_init
(
struct
wl1271
*
wl
)
{
int
ret
=
0
;
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
{
u32
host_cfg_bitmap
=
HOST_IF_CFG_RX_FIFO_ENABLE
;
if
(
wl
->
quirks
&
WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT
)
/* Enable SDIO padding */
host_cfg_bitmap
|=
HOST_IF_CFG_TX_PAD_TO_SDIO_BLK
;
/* Must be before wl1271_acx_init_mem_config() */
ret
=
wl1271_acx_host_if_cfg_bitmap
(
wl
,
host_cfg_bitmap
);
if
(
ret
<
0
)
goto
out
;
}
out:
return
ret
;
}
int
wl1271_hw_init
(
struct
wl1271
*
wl
)
{
struct
conf_tx_ac_category
*
conf_ac
;
...
...
@@ -511,14 +535,25 @@ int wl1271_hw_init(struct wl1271 *wl)
int
ret
,
i
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
ret
=
wl128x_cmd_general_parms
(
wl
);
else
ret
=
wl1271_cmd_general_parms
(
wl
);
if
(
ret
<
0
)
return
ret
;
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
ret
=
wl128x_cmd_radio_parms
(
wl
);
else
ret
=
wl1271_cmd_radio_parms
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Chip-specific init */
ret
=
wl1271_chip_specific_init
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Mode specific init */
if
(
is_ap
)
ret
=
wl1271_ap_hw_init
(
wl
);
...
...
drivers/net/wireless/wl12xx/init.h
View file @
e55034e9
...
...
@@ -31,6 +31,7 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl);
int
wl1271_init_phy_config
(
struct
wl1271
*
wl
);
int
wl1271_init_pta
(
struct
wl1271
*
wl
);
int
wl1271_init_energy_detection
(
struct
wl1271
*
wl
);
int
wl1271_chip_specific_init
(
struct
wl1271
*
wl
);
int
wl1271_hw_init
(
struct
wl1271
*
wl
);
#endif
drivers/net/wireless/wl12xx/io.c
View file @
e55034e9
...
...
@@ -29,6 +29,7 @@
#include "wl12xx.h"
#include "wl12xx_80211.h"
#include "io.h"
#include "tx.h"
#define OCP_CMD_LOOP 32
...
...
@@ -43,6 +44,16 @@
#define OCP_STATUS_REQ_FAILED 0x20000
#define OCP_STATUS_RESP_ERROR 0x30000
bool
wl1271_set_block_size
(
struct
wl1271
*
wl
)
{
if
(
wl
->
if_ops
->
set_block_size
)
{
wl
->
if_ops
->
set_block_size
(
wl
,
WL12XX_BUS_BLOCK_SIZE
);
return
true
;
}
return
false
;
}
void
wl1271_disable_interrupts
(
struct
wl1271
*
wl
)
{
wl
->
if_ops
->
disable_irq
(
wl
);
...
...
drivers/net/wireless/wl12xx/io.h
View file @
e55034e9
...
...
@@ -169,5 +169,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl);
struct
ieee80211_hw
*
wl1271_alloc_hw
(
void
);
int
wl1271_free_hw
(
struct
wl1271
*
wl
);
irqreturn_t
wl1271_irq
(
int
irq
,
void
*
data
);
bool
wl1271_set_block_size
(
struct
wl1271
*
wl
);
int
wl1271_tx_dummy_packet
(
struct
wl1271
*
wl
);
void
wl1271_configure_filters
(
struct
wl1271
*
wl
,
unsigned
int
filters
);
#endif
drivers/net/wireless/wl12xx/main.c
View file @
e55034e9
This diff is collapsed.
Click to expand it.
drivers/net/wireless/wl12xx/ps.c
View file @
e55034e9
...
...
@@ -149,9 +149,6 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
case
STATION_ACTIVE_MODE
:
default:
wl1271_debug
(
DEBUG_PSM
,
"leaving psm"
);
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* disable beacon early termination */
ret
=
wl1271_acx_bet_enable
(
wl
,
false
);
...
...
drivers/net/wireless/wl12xx/reg.h
View file @
e55034e9
...
...
@@ -207,6 +207,8 @@
#define CHIP_ID_1271_PG10 (0x4030101)
#define CHIP_ID_1271_PG20 (0x4030111)
#define CHIP_ID_1283_PG10 (0x05030101)
#define CHIP_ID_1283_PG20 (0x05030111)
#define ENABLE (REGISTERS_BASE + 0x5450)
...
...
@@ -452,24 +454,11 @@
#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
/*
* NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
* for platforms using active high interrupt level
*/
#ifdef USE_ACTIVE_HIGH
#define HI_CFG_DEF_VAL \
(HI_CFG_UART_ENABLE | \
HI_CFG_RST232_ENABLE | \
HI_CFG_CLOCK_REQ_SELECT | \
HI_CFG_HOST_INT_ENABLE)
#else
#define HI_CFG_DEF_VAL \
(HI_CFG_UART_ENABLE | \
HI_CFG_RST232_ENABLE | \
HI_CFG_CLOCK_REQ_SELECT | \
HI_CFG_HOST_INT_ENABLE)
#endif
#define REF_FREQ_19_2 0
#define REF_FREQ_26_0 1
...
...
drivers/net/wireless/wl12xx/rx.c
View file @
e55034e9
...
...
@@ -48,18 +48,14 @@ static void wl1271_rx_status(struct wl1271 *wl,
struct
ieee80211_rx_status
*
status
,
u8
beacon
)
{
enum
ieee80211_band
desc_band
;
memset
(
status
,
0
,
sizeof
(
struct
ieee80211_rx_status
));
status
->
band
=
wl
->
band
;
if
((
desc
->
flags
&
WL1271_RX_DESC_BAND_MASK
)
==
WL1271_RX_DESC_BAND_BG
)
desc_
band
=
IEEE80211_BAND_2GHZ
;
status
->
band
=
IEEE80211_BAND_2GHZ
;
else
desc_
band
=
IEEE80211_BAND_5GHZ
;
status
->
band
=
IEEE80211_BAND_5GHZ
;
status
->
rate_idx
=
wl1271_rate_to_idx
(
desc
->
rate
,
desc_
band
);
status
->
rate_idx
=
wl1271_rate_to_idx
(
desc
->
rate
,
status
->
band
);
#ifdef CONFIG_WL12XX_HT
/* 11n support */
...
...
@@ -76,7 +72,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
*/
wl
->
noise
=
desc
->
rssi
-
(
desc
->
snr
>>
1
);
status
->
freq
=
ieee80211_channel_to_frequency
(
desc
->
channel
,
desc_band
);
status
->
freq
=
ieee80211_channel_to_frequency
(
desc
->
channel
,
status
->
band
);
if
(
desc
->
flags
&
WL1271_RX_DESC_ENCRYPT_MASK
)
{
status
->
flag
|=
RX_FLAG_IV_STRIPPED
|
RX_FLAG_MMIC_STRIPPED
;
...
...
@@ -163,18 +160,25 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
break
;
}
if
(
wl
->
chip
.
id
!=
CHIP_ID_1283_PG20
)
{
/*
* Choose the block we want to read
* For aggregated packets, only the first memory block should
*
be retrieved. The FW takes care of the rest.
* For aggregated packets, only the first memory block
* should
be retrieved. The FW takes care of the rest.
*/
mem_block
=
wl1271_rx_get_mem_block
(
status
,
drv_rx_counter
);
mem_block
=
wl1271_rx_get_mem_block
(
status
,
drv_rx_counter
);
wl
->
rx_mem_pool_addr
.
addr
=
(
mem_block
<<
8
)
+
le32_to_cpu
(
wl_mem_map
->
packet_memory_pool_start
);
wl
->
rx_mem_pool_addr
.
addr_extra
=
wl
->
rx_mem_pool_addr
.
addr
+
4
;
wl1271_write
(
wl
,
WL1271_SLV_REG_DATA
,
&
wl
->
rx_mem_pool_addr
,
wl1271_write
(
wl
,
WL1271_SLV_REG_DATA
,
&
wl
->
rx_mem_pool_addr
,
sizeof
(
wl
->
rx_mem_pool_addr
),
false
);
}
/* Read all available packets at once */
wl1271_read
(
wl
,
WL1271_SLV_MEM_DATA
,
wl
->
aggr_buf
,
...
...
drivers/net/wireless/wl12xx/scan.c
View file @
e55034e9
...
...
@@ -48,8 +48,7 @@ void wl1271_scan_complete_work(struct work_struct *work)
goto
out
;
wl
->
scan
.
state
=
WL1271_SCAN_STATE_IDLE
;
kfree
(
wl
->
scan
.
scanned_ch
);
wl
->
scan
.
scanned_ch
=
NULL
;
memset
(
wl
->
scan
.
scanned_ch
,
0
,
sizeof
(
wl
->
scan
.
scanned_ch
));
wl
->
scan
.
req
=
NULL
;
ieee80211_scan_completed
(
wl
->
hw
,
false
);
...
...
@@ -87,7 +86,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
flags
=
req
->
channels
[
i
]
->
flags
;
if
(
!
wl
->
scan
.
scanned_ch
[
i
]
&&
if
(
!
test_bit
(
i
,
wl
->
scan
.
scanned_ch
)
&&
!
(
flags
&
IEEE80211_CHAN_DISABLED
)
&&
((
!!
(
flags
&
IEEE80211_CHAN_PASSIVE_SCAN
))
==
passive
)
&&
(
req
->
channels
[
i
]
->
band
==
band
))
{
...
...
@@ -124,7 +123,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
memset
(
&
channels
[
j
].
bssid_msb
,
0xff
,
2
);
/* Mark the channels we already used */
wl
->
scan
.
scanned_ch
[
i
]
=
true
;
set_bit
(
i
,
wl
->
scan
.
scanned_ch
)
;
j
++
;
}
...
...
@@ -291,6 +290,12 @@ void wl1271_scan_stm(struct wl1271 *wl)
int
wl1271_scan
(
struct
wl1271
*
wl
,
const
u8
*
ssid
,
size_t
ssid_len
,
struct
cfg80211_scan_request
*
req
)
{
/*
* cfg80211 should guarantee that we don't get more channels
* than what we have registered.
*/
BUG_ON
(
req
->
n_channels
>
WL1271_MAX_CHANNELS
);
if
(
wl
->
scan
.
state
!=
WL1271_SCAN_STATE_IDLE
)
return
-
EBUSY
;
...
...
@@ -304,10 +309,8 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
}
wl
->
scan
.
req
=
req
;
memset
(
wl
->
scan
.
scanned_ch
,
0
,
sizeof
(
wl
->
scan
.
scanned_ch
));
wl
->
scan
.
scanned_ch
=
kcalloc
(
req
->
n_channels
,
sizeof
(
*
wl
->
scan
.
scanned_ch
),
GFP_KERNEL
);
/* we assume failure so that timeout scenarios are handled correctly */
wl
->
scan
.
failed
=
true
;
ieee80211_queue_delayed_work
(
wl
->
hw
,
&
wl
->
scan_complete_work
,
...
...
drivers/net/wireless/wl12xx/sdio.c
View file @
e55034e9
...
...
@@ -51,6 +51,13 @@ static const struct sdio_device_id wl1271_devices[] = {
};
MODULE_DEVICE_TABLE
(
sdio
,
wl1271_devices
);
static
void
wl1271_sdio_set_block_size
(
struct
wl1271
*
wl
,
unsigned
int
blksz
)
{
sdio_claim_host
(
wl
->
if_priv
);
sdio_set_block_size
(
wl
->
if_priv
,
blksz
);
sdio_release_host
(
wl
->
if_priv
);
}
static
inline
struct
sdio_func
*
wl_to_func
(
struct
wl1271
*
wl
)
{
return
wl
->
if_priv
;
...
...
@@ -203,7 +210,8 @@ static struct wl1271_if_operations sdio_ops = {
.
power
=
wl1271_sdio_set_power
,
.
dev
=
wl1271_sdio_wl_to_dev
,
.
enable_irq
=
wl1271_sdio_enable_interrupts
,
.
disable_irq
=
wl1271_sdio_disable_interrupts
.
disable_irq
=
wl1271_sdio_disable_interrupts
,
.
set_block_size
=
wl1271_sdio_set_block_size
,
};
static
int
__devinit
wl1271_probe
(
struct
sdio_func
*
func
,
...
...
@@ -212,6 +220,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
struct
ieee80211_hw
*
hw
;
const
struct
wl12xx_platform_data
*
wlan_data
;
struct
wl1271
*
wl
;
unsigned
long
irqflags
;
int
ret
;
/* We are only able to handle the wlan function */
...
...
@@ -230,6 +239,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
/* Grab access to FN0 for ELP reg. */
func
->
card
->
quirks
|=
MMC_QUIRK_LENIENT_FN0
;
/* Use block mode for transferring over one block size of data */
func
->
card
->
quirks
|=
MMC_QUIRK_BLKSZ_FOR_BYTE_MODE
;
wlan_data
=
wl12xx_get_platform_data
();
if
(
IS_ERR
(
wlan_data
))
{
ret
=
PTR_ERR
(
wlan_data
);
...
...
@@ -239,9 +251,16 @@ static int __devinit wl1271_probe(struct sdio_func *func,
wl
->
irq
=
wlan_data
->
irq
;
wl
->
ref_clock
=
wlan_data
->
board_ref_clock
;
wl
->
tcxo_clock
=
wlan_data
->
board_tcxo_clock
;
wl
->
platform_quirks
=
wlan_data
->
platform_quirks
;
if
(
wl
->
platform_quirks
&
WL12XX_PLATFORM_QUIRK_EDGE_IRQ
)
irqflags
=
IRQF_TRIGGER_RISING
;
else
irqflags
=
IRQF_TRIGGER_HIGH
|
IRQF_ONESHOT
;
ret
=
request_threaded_irq
(
wl
->
irq
,
wl1271_hardirq
,
wl1271_irq
,
IRQF_TRIGGER_HIGH
|
IRQF_ONESHOT
,
irqflags
,
DRIVER_NAME
,
wl
);
if
(
ret
<
0
)
{
wl1271_error
(
"request_irq() failed: %d"
,
ret
);
...
...
@@ -343,4 +362,6 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL1271_FW_NAME
);
MODULE_FIRMWARE
(
WL1271_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_AP_FW_NAME
);
drivers/net/wireless/wl12xx/sdio_test.c
View file @
e55034e9
...
...
@@ -189,7 +189,12 @@ 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
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
ret
=
request_firmware
(
&
fw
,
WL128X_FW_NAME
,
wl1271_wl_to_dev
(
wl
));
else
ret
=
request_firmware
(
&
fw
,
WL1271_FW_NAME
,
wl1271_wl_to_dev
(
wl
));
if
(
ret
<
0
)
{
wl1271_error
(
"could not get firmware: %d"
,
ret
);
...
...
@@ -227,14 +232,14 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
const
struct
firmware
*
fw
;
int
ret
;
ret
=
request_firmware
(
&
fw
,
WL12
71
_NVS_NAME
,
wl1271_wl_to_dev
(
wl
));
ret
=
request_firmware
(
&
fw
,
WL12
XX
_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
);
wl
->
nvs
=
kmemdup
(
fw
->
data
,
fw
->
size
,
GFP_KERNEL
);
if
(
!
wl
->
nvs
)
{
wl1271_error
(
"could not allocate memory for the nvs file"
);
...
...
@@ -288,6 +293,11 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
wl1271_notice
(
"chip id 0x%x (1271 PG20)"
,
wl
->
chip
.
id
);
break
;
case
CHIP_ID_1283_PG20
:
wl1271_notice
(
"chip id 0x%x (1283 PG20)"
,
wl
->
chip
.
id
);
break
;
case
CHIP_ID_1283_PG10
:
default:
wl1271_warning
(
"unsupported chip id: 0x%x"
,
wl
->
chip
.
id
);
return
-
ENODEV
;
...
...
@@ -407,6 +417,9 @@ static int __devinit wl1271_probe(struct sdio_func *func,
/* Grab access to FN0 for ELP reg. */
func
->
card
->
quirks
|=
MMC_QUIRK_LENIENT_FN0
;
/* Use block mode for transferring over one block size of data */
func
->
card
->
quirks
|=
MMC_QUIRK_BLKSZ_FOR_BYTE_MODE
;
wlan_data
=
wl12xx_get_platform_data
();
if
(
IS_ERR
(
wlan_data
))
{
ret
=
PTR_ERR
(
wlan_data
);
...
...
@@ -416,6 +429,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
wl
->
irq
=
wlan_data
->
irq
;
wl
->
ref_clock
=
wlan_data
->
board_ref_clock
;
wl
->
tcxo_clock
=
wlan_data
->
board_tcxo_clock
;
sdio_set_drvdata
(
func
,
wl_test
);
...
...
drivers/net/wireless/wl12xx/spi.c
View file @
e55034e9
...
...
@@ -355,7 +355,8 @@ static struct wl1271_if_operations spi_ops = {
.
power
=
wl1271_spi_set_power
,
.
dev
=
wl1271_spi_wl_to_dev
,
.
enable_irq
=
wl1271_spi_enable_interrupts
,
.
disable_irq
=
wl1271_spi_disable_interrupts
.
disable_irq
=
wl1271_spi_disable_interrupts
,
.
set_block_size
=
NULL
,
};
static
int
__devinit
wl1271_probe
(
struct
spi_device
*
spi
)
...
...
@@ -363,6 +364,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
struct
wl12xx_platform_data
*
pdata
;
struct
ieee80211_hw
*
hw
;
struct
wl1271
*
wl
;
unsigned
long
irqflags
;
int
ret
;
pdata
=
spi
->
dev
.
platform_data
;
...
...
@@ -400,6 +402,13 @@ static int __devinit wl1271_probe(struct spi_device *spi)
}
wl
->
ref_clock
=
pdata
->
board_ref_clock
;
wl
->
tcxo_clock
=
pdata
->
board_tcxo_clock
;
wl
->
platform_quirks
=
pdata
->
platform_quirks
;
if
(
wl
->
platform_quirks
&
WL12XX_PLATFORM_QUIRK_EDGE_IRQ
)
irqflags
=
IRQF_TRIGGER_RISING
;
else
irqflags
=
IRQF_TRIGGER_HIGH
|
IRQF_ONESHOT
;
wl
->
irq
=
spi
->
irq
;
if
(
wl
->
irq
<
0
)
{
...
...
@@ -409,7 +418,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
}
ret
=
request_threaded_irq
(
wl
->
irq
,
wl1271_hardirq
,
wl1271_irq
,
IRQF_TRIGGER_HIGH
|
IRQF_ONESHOT
,
irqflags
,
DRIVER_NAME
,
wl
);
if
(
ret
<
0
)
{
wl1271_error
(
"request_irq() failed: %d"
,
ret
);
...
...
@@ -490,5 +499,7 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL1271_FW_NAME
);
MODULE_FIRMWARE
(
WL1271_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_AP_FW_NAME
);
MODULE_ALIAS
(
"spi:wl1271"
);
drivers/net/wireless/wl12xx/testmode.c
View file @
e55034e9
...
...
@@ -27,6 +27,7 @@
#include "wl12xx.h"
#include "acx.h"
#include "reg.h"
#define WL1271_TM_MAX_DATA_LENGTH 1024
...
...
@@ -204,7 +205,10 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
kfree
(
wl
->
nvs
);
if
(
len
!=
sizeof
(
struct
wl1271_nvs_file
))
if
((
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
&&
(
len
!=
sizeof
(
struct
wl128x_nvs_file
)))
return
-
EINVAL
;
else
if
(
len
!=
sizeof
(
struct
wl1271_nvs_file
))
return
-
EINVAL
;
wl
->
nvs
=
kzalloc
(
len
,
GFP_KERNEL
);
...
...
drivers/net/wireless/wl12xx/tx.c
View file @
e55034e9
This diff is collapsed.
Click to expand it.
drivers/net/wireless/wl12xx/tx.h
View file @
e55034e9
...
...
@@ -25,7 +25,6 @@
#ifndef __TX_H__
#define __TX_H__
#define TX_HW_BLOCK_SPARE 2
#define TX_HW_BLOCK_SIZE 252
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
...
...
@@ -41,6 +40,7 @@
BIT(8) | BIT(9))
#define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11))
#define TX_HW_ATTR_TX_CMPLT_REQ BIT(12)
#define TX_HW_ATTR_TX_DUMMY_REQ BIT(13)
#define TX_HW_ATTR_OFST_SAVE_RETRIES 0
#define TX_HW_ATTR_OFST_HEADER_PAD 1
...
...
@@ -55,20 +55,60 @@
#define WL1271_TX_ALIGN_TO 4
#define WL1271_TKIP_IV_SPACE 4
/* Used for management frames and dummy packets */
#define WL1271_TID_MGMT 7
struct
wl127x_tx_mem
{
/*
* Number of extra memory blocks to allocate for this packet
* in addition to the number of blocks derived from the packet
* length.
*/
u8
extra_blocks
;
/*
* Total number of memory blocks allocated by the host for
* this packet. Must be equal or greater than the actual
* blocks number allocated by HW.
*/
u8
total_mem_blocks
;
}
__packed
;
struct
wl128x_tx_mem
{
/*
* Total number of memory blocks allocated by the host for
* this packet.
*/
u8
total_mem_blocks
;
/*
* Number of extra bytes, at the end of the frame. the host
* uses this padding to complete each frame to integer number
* of SDIO blocks.
*/
u8
extra_bytes
;
}
__packed
;
/*
* On wl128x based devices, when TX packets are aggregated, each packet
* size must be aligned to the SDIO block size. The maximum block size
* is bounded by the type of the padded bytes field that is sent to the
* FW. Currently the type is u8, so the maximum block size is 256 bytes.
*/
#define WL12XX_BUS_BLOCK_SIZE min(512u, \
(1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes))))
struct
wl1271_tx_hw_descr
{
/* Length of packet in words, including descriptor+header+data */
__le16
length
;
/* Number of extra memory blocks to allocate for this packet in
addition to the number of blocks derived from the packet length */
u8
extra_mem_blocks
;
/* Total number of memory blocks allocated by the host for this packet.
Must be equal or greater than the actual blocks number allocated by
HW!! */
u8
total_mem_blocks
;
union
{
struct
wl127x_tx_mem
wl127x_mem
;
struct
wl128x_tx_mem
wl128x_mem
;
}
__packed
;
/* Device time (in us) when the packet arrived to the driver */
__le32
start_time
;
/* Max delay in TUs until transmission. The last device time the
packet can be transmitted is: startTime+(1024*LifeTime) */
/*
* Max delay in TUs until transmission. The last device time the
* packet can be transmitted is: start_time + (1024 * life_time)
*/
__le16
life_time
;
/* Bitwise fields - see TX_ATTR... definitions above. */
__le16
tx_attr
;
...
...
drivers/net/wireless/wl12xx/wl12xx.h
View file @
e55034e9
...
...
@@ -131,9 +131,16 @@ extern u32 wl12xx_debug_level;
#define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin"
#define WL1271_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin"
#define WL128X_FW_NAME "ti-connectivity/wl128x-fw.bin"
#define WL127X_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin"
#define WL128X_AP_FW_NAME "ti-connectivity/wl128x-fw-ap.bin"
#define WL1271_NVS_NAME "ti-connectivity/wl1271-nvs.bin"
/*
* wl127x and wl128x are using the same NVS file name. However, the
* ini parameters between them are different. The driver validates
* the correct NVS size in wl1271_boot_upload_nvs().
*/
#define WL12XX_NVS_NAME "ti-connectivity/wl1271-nvs.bin"
#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
...
...
@@ -200,13 +207,29 @@ struct wl1271_partition_set {
struct
wl1271
;
#define WL12XX_NUM_FW_VER 5
enum
{
FW_VER_CHIP
,
FW_VER_IF_TYPE
,
FW_VER_MAJOR
,
FW_VER_SUBTYPE
,
FW_VER_MINOR
,
NUM_FW_VER
};
#define FW_VER_CHIP_WL127X 6
#define FW_VER_CHIP_WL128X 7
#define FW_VER_IF_TYPE_STA 1
#define FW_VER_IF_TYPE_AP 2
#define FW_VER_MINOR_1_SPARE_STA_MIN 58
#define FW_VER_MINOR_1_SPARE_AP_MIN 47
/* FIXME: I'm not sure about this structure name */
struct
wl1271_chip
{
u32
id
;
char
fw_ver_str
[
ETHTOOL_BUSINFO_LEN
];
unsigned
int
fw_ver
[
WL12XX_
NUM_FW_VER
];
unsigned
int
fw_ver
[
NUM_FW_VER
];
};
struct
wl1271_stats
{
...
...
@@ -261,6 +284,8 @@ struct wl1271_fw_sta_status {
u8
tx_total
;
u8
reserved1
;
__le16
reserved2
;
/* Total structure size is 68 bytes */
u32
padding
;
}
__packed
;
struct
wl1271_fw_full_status
{
...
...
@@ -277,9 +302,10 @@ struct wl1271_rx_mem_pool_addr {
u32
addr_extra
;
};
#define WL1271_MAX_CHANNELS 64
struct
wl1271_scan
{
struct
cfg80211_scan_request
*
req
;
bool
*
scanned_ch
;
unsigned
long
scanned_ch
[
BITS_TO_LONGS
(
WL1271_MAX_CHANNELS
)]
;
bool
failed
;
u8
state
;
u8
ssid
[
IW_ESSID_MAX_SIZE
+
1
];
...
...
@@ -297,6 +323,7 @@ struct wl1271_if_operations {
struct
device
*
(
*
dev
)(
struct
wl1271
*
wl
);
void
(
*
enable_irq
)(
struct
wl1271
*
wl
);
void
(
*
disable_irq
)(
struct
wl1271
*
wl
);
void
(
*
set_block_size
)
(
struct
wl1271
*
wl
,
unsigned
int
blksz
);
};
#define MAX_NUM_KEYS 14
...
...
@@ -327,7 +354,9 @@ enum wl12xx_flags {
WL1271_FLAG_PSPOLL_FAILURE
,
WL1271_FLAG_STA_STATE_SENT
,
WL1271_FLAG_FW_TX_BUSY
,
WL1271_FLAG_AP_STARTED
WL1271_FLAG_AP_STARTED
,
WL1271_FLAG_IF_INITIALIZED
,
WL1271_FLAG_DUMMY_PACKET_PENDING
,
};
struct
wl1271_link
{
...
...
@@ -371,7 +400,7 @@ struct wl1271 {
u8
*
fw
;
size_t
fw_len
;
u8
fw_bss_type
;
struct
wl1271_nvs_file
*
nvs
;
void
*
nvs
;
size_t
nvs_len
;
s8
hw_pg_ver
;
...
...
@@ -389,6 +418,7 @@ struct wl1271 {
/* Accounting for allocated / available TX blocks on HW */
u32
tx_blocks_freed
[
NUM_TX_QUEUES
];
u32
tx_blocks_available
;
u32
tx_allocated_blocks
;
u32
tx_results_count
;
/* Transmitted TX packets counter for chipset interface */
...
...
@@ -430,6 +460,9 @@ struct wl1271 {
/* Intermediate buffer, used for packet aggregation */
u8
*
aggr_buf
;
/* Reusable dummy packet template */
struct
sk_buff
*
dummy_packet
;
/* Network stack work */
struct
work_struct
netstack_work
;
...
...
@@ -527,6 +560,8 @@ struct wl1271 {
bool
ba_support
;
u8
ba_rx_bitmap
;
int
tcxo_clock
;
/*
* AP-mode - links indexed by HLID. The global and broadcast links
* are always active.
...
...
@@ -544,6 +579,9 @@ struct wl1271 {
/* Quirks of specific hardware revisions */
unsigned
int
quirks
;
/* Platform limitations */
unsigned
int
platform_quirks
;
};
struct
wl1271_station
{
...
...
@@ -578,4 +616,13 @@ int wl1271_plt_stop(struct wl1271 *wl);
/* Each RX/TX transaction requires an end-of-transaction transfer */
#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
/*
* Older firmwares use 2 spare TX blocks
* (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
*/
#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
/* WL128X requires aggregated packets to be aligned to the SDIO block size */
#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
#endif
include/linux/wl12xx.h
View file @
e55034e9
...
...
@@ -24,12 +24,26 @@
#ifndef _LINUX_WL12XX_H
#define _LINUX_WL12XX_H
/*
The board r
eference clock values */
/*
R
eference clock values */
enum
{
WL12XX_REFCLOCK_19
=
0
,
/* 19.2 MHz */
WL12XX_REFCLOCK_26
=
1
,
/* 26 MHz */
WL12XX_REFCLOCK_38
=
2
,
/* 38.4 MHz */
WL12XX_REFCLOCK_54
=
3
,
/* 54 MHz */
WL12XX_REFCLOCK_52
=
3
,
/* 52 MHz */
WL12XX_REFCLOCK_38_XTAL
=
4
,
/* 38.4 MHz, XTAL */
WL12XX_REFCLOCK_26_XTAL
=
5
,
/* 26 MHz, XTAL */
};
/* TCXO clock values */
enum
{
WL12XX_TCXOCLOCK_19_2
=
0
,
/* 19.2MHz */
WL12XX_TCXOCLOCK_26
=
1
,
/* 26 MHz */
WL12XX_TCXOCLOCK_38_4
=
2
,
/* 38.4MHz */
WL12XX_TCXOCLOCK_52
=
3
,
/* 52 MHz */
WL12XX_TCXOCLOCK_16_368
=
4
,
/* 16.368 MHz */
WL12XX_TCXOCLOCK_32_736
=
5
,
/* 32.736 MHz */
WL12XX_TCXOCLOCK_16_8
=
6
,
/* 16.8 MHz */
WL12XX_TCXOCLOCK_33_6
=
7
,
/* 33.6 MHz */
};
struct
wl12xx_platform_data
{
...
...
@@ -38,8 +52,13 @@ struct wl12xx_platform_data {
int
irq
;
bool
use_eeprom
;
int
board_ref_clock
;
int
board_tcxo_clock
;
unsigned
long
platform_quirks
;
};
/* Platform does not support level trigger interrupts */
#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ BIT(0)
#ifdef CONFIG_WL12XX_PLATFORM_DATA
int
wl12xx_set_platform_data
(
const
struct
wl12xx_platform_data
*
data
);
...
...
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