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
8715d941
Commit
8715d941
authored
Feb 22, 2012
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
ca994a36
51c4ed95
Changes
33
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
1386 additions
and
798 deletions
+1386
-798
drivers/net/wireless/wl1251/Makefile
drivers/net/wireless/wl1251/Makefile
+2
-0
drivers/net/wireless/wl1251/boot.c
drivers/net/wireless/wl1251/boot.c
+0
-2
drivers/net/wireless/wl1251/io.h
drivers/net/wireless/wl1251/io.h
+4
-5
drivers/net/wireless/wl1251/wl1251.h
drivers/net/wireless/wl1251/wl1251.h
+1
-1
drivers/net/wireless/wl12xx/Makefile
drivers/net/wireless/wl12xx/Makefile
+2
-0
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+11
-6
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+77
-72
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+15
-90
drivers/net/wireless/wl12xx/boot.h
drivers/net/wireless/wl12xx/boot.h
+0
-10
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+105
-38
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+82
-66
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+43
-8
drivers/net/wireless/wl12xx/debug.h
drivers/net/wireless/wl12xx/debug.h
+1
-0
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+239
-2
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+2
-152
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/event.h
+12
-8
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+36
-19
drivers/net/wireless/wl12xx/io.c
drivers/net/wireless/wl12xx/io.c
+59
-0
drivers/net/wireless/wl12xx/io.h
drivers/net/wireless/wl12xx/io.h
+2
-0
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+466
-208
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+24
-10
drivers/net/wireless/wl12xx/ps.h
drivers/net/wireless/wl12xx/ps.h
+1
-1
drivers/net/wireless/wl12xx/reg.h
drivers/net/wireless/wl12xx/reg.h
+27
-0
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+1
-1
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.c
+30
-26
drivers/net/wireless/wl12xx/scan.h
drivers/net/wireless/wl12xx/scan.h
+1
-1
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/sdio.c
+16
-13
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/spi.c
+6
-2
drivers/net/wireless/wl12xx/testmode.c
drivers/net/wireless/wl12xx/testmode.c
+50
-0
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+34
-41
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+4
-1
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+32
-14
drivers/net/wireless/wl12xx/wl12xx_80211.h
drivers/net/wireless/wl12xx/wl12xx_80211.h
+1
-1
No files found.
drivers/net/wireless/wl1251/Makefile
View file @
8715d941
...
...
@@ -6,3 +6,5 @@ wl1251_sdio-objs += sdio.o
obj-$(CONFIG_WL1251)
+=
wl1251.o
obj-$(CONFIG_WL1251_SPI)
+=
wl1251_spi.o
obj-$(CONFIG_WL1251_SDIO)
+=
wl1251_sdio.o
ccflags-y
+=
-D__CHECK_ENDIAN__
drivers/net/wireless/wl1251/boot.c
View file @
8715d941
...
...
@@ -464,8 +464,6 @@ static int wl1251_boot_upload_nvs(struct wl1251 *wl)
val
=
(
nvs_ptr
[
0
]
|
(
nvs_ptr
[
1
]
<<
8
)
|
(
nvs_ptr
[
2
]
<<
16
)
|
(
nvs_ptr
[
3
]
<<
24
));
val
=
cpu_to_le32
(
val
);
wl1251_debug
(
DEBUG_BOOT
,
"nvs write table 0x%x: 0x%x"
,
nvs_start
,
val
);
...
...
drivers/net/wireless/wl1251/io.h
View file @
8715d941
...
...
@@ -36,16 +36,15 @@
static
inline
u32
wl1251_read32
(
struct
wl1251
*
wl
,
int
addr
)
{
u32
response
;
wl
->
if_ops
->
read
(
wl
,
addr
,
&
response
,
sizeof
(
u32
));
wl
->
if_ops
->
read
(
wl
,
addr
,
&
wl
->
buffer_32
,
sizeof
(
wl
->
buffer_32
));
return
response
;
return
le32_to_cpu
(
wl
->
buffer_32
)
;
}
static
inline
void
wl1251_write32
(
struct
wl1251
*
wl
,
int
addr
,
u32
val
)
{
wl
->
if_ops
->
write
(
wl
,
addr
,
&
val
,
sizeof
(
u32
));
wl
->
buffer_32
=
cpu_to_le32
(
val
);
wl
->
if_ops
->
write
(
wl
,
addr
,
&
wl
->
buffer_32
,
sizeof
(
wl
->
buffer_32
));
}
static
inline
u32
wl1251_read_elp
(
struct
wl1251
*
wl
,
int
addr
)
...
...
drivers/net/wireless/wl1251/wl1251.h
View file @
8715d941
...
...
@@ -380,7 +380,7 @@ struct wl1251 {
struct
wl1251_stats
stats
;
struct
wl1251_debugfs
debugfs
;
u
32
buffer_32
;
__le
32
buffer_32
;
u32
buffer_cmd
;
u8
buffer_busyword
[
WL1251_BUSY_WORD_LEN
];
struct
wl1251_rx_descriptor
*
rx_descriptor
;
...
...
drivers/net/wireless/wl12xx/Makefile
View file @
8715d941
...
...
@@ -11,3 +11,5 @@ obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
# small builtin driver bit
obj-$(CONFIG_WL12XX_PLATFORM_DATA)
+=
wl12xx_platform_data.o
ccflags-y
+=
-D__CHECK_ENDIAN__
drivers/net/wireless/wl12xx/acx.c
View file @
8715d941
...
...
@@ -34,12 +34,14 @@
#include "reg.h"
#include "ps.h"
int
wl1271_acx_wake_up_conditions
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
)
int
wl1271_acx_wake_up_conditions
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u8
wake_up_event
,
u8
listen_interval
)
{
struct
acx_wake_up_condition
*
wake_up
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx wake up conditions"
);
wl1271_debug
(
DEBUG_ACX
,
"acx wake up conditions (wake_up_event %d listen_interval %d)"
,
wake_up_event
,
listen_interval
);
wake_up
=
kzalloc
(
sizeof
(
*
wake_up
),
GFP_KERNEL
);
if
(
!
wake_up
)
{
...
...
@@ -48,8 +50,8 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
}
wake_up
->
role_id
=
wlvif
->
role_id
;
wake_up
->
wake_up_event
=
w
l
->
conf
.
conn
.
w
ake_up_event
;
wake_up
->
listen_interval
=
wl
->
conf
.
conn
.
listen_interval
;
wake_up
->
wake_up_event
=
wake_up_event
;
wake_up
->
listen_interval
=
listen_interval
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_WAKE_UP_CONDITIONS
,
wake_up
,
sizeof
(
*
wake_up
));
...
...
@@ -1459,9 +1461,10 @@ int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
return
ret
;
}
int
wl1271_acx_tsf_info
(
struct
wl1271
*
wl
,
u64
*
mactime
)
int
wl12xx_acx_tsf_info
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u64
*
mactime
)
{
struct
wl12
71
_acx_fw_tsf_information
*
tsf_info
;
struct
wl12
xx
_acx_fw_tsf_information
*
tsf_info
;
int
ret
;
tsf_info
=
kzalloc
(
sizeof
(
*
tsf_info
),
GFP_KERNEL
);
...
...
@@ -1470,6 +1473,8 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
goto
out
;
}
tsf_info
->
role_id
=
wlvif
->
role_id
;
ret
=
wl1271_cmd_interrogate
(
wl
,
ACX_TSF_INFO
,
tsf_info
,
sizeof
(
*
tsf_info
));
if
(
ret
<
0
)
{
...
...
drivers/net/wireless/wl12xx/acx.h
View file @
8715d941
...
...
@@ -995,15 +995,17 @@ struct wl1271_acx_ba_receiver_setup {
u8
padding
[
2
];
}
__packed
;
struct
wl12
71
_acx_fw_tsf_information
{
struct
wl12
xx
_acx_fw_tsf_information
{
struct
acx_header
header
;
u8
role_id
;
u8
padding1
[
3
];
__le32
current_tsf_high
;
__le32
current_tsf_low
;
__le32
last_bttt_high
;
__le32
last_tbtt_low
;
u8
last_dtim_count
;
u8
padding
[
3
];
u8
padding
2
[
3
];
}
__packed
;
struct
wl1271_acx_ps_rx_streaming
{
...
...
@@ -1151,79 +1153,81 @@ struct wl12xx_acx_config_hangover {
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
ACX_SLOT
=
0x0004
,
ACX_AC_CFG
=
0x0007
,
ACX_MEM_MAP
=
0x0008
,
ACX_AID
=
0x000A
,
ACX_MEDIUM_USAGE
=
0x000F
,
ACX_TX_QUEUE_CFG
=
0x0011
,
/* FIXME: only used by wl1251 */
ACX_STATISTICS
=
0x0013
,
/* Debug API */
ACX_PWR_CONSUMPTION_STATISTICS
=
0x0014
,
ACX_FEATURE_CFG
=
0x0015
,
ACX_TID_CFG
=
0x001A
,
ACX_PS_RX_STREAMING
=
0x001B
,
ACX_BEACON_FILTER_OPT
=
0x001F
,
ACX_NOISE_HIST
=
0x0021
,
ACX_HDK_VERSION
=
0x0022
,
/* ??? */
ACX_PD_THRESHOLD
=
0x0023
,
ACX_TX_CONFIG_OPT
=
0x0024
,
ACX_CCA_THRESHOLD
=
0x0025
,
ACX_EVENT_MBOX_MASK
=
0x0026
,
ACX_CONN_MONIT_PARAMS
=
0x002D
,
ACX_BCN_DTIM_OPTIONS
=
0x0031
,
ACX_SG_ENABLE
=
0x0032
,
ACX_SG_CFG
=
0x0033
,
ACX_FM_COEX_CFG
=
0x0034
,
ACX_BEACON_FILTER_TABLE
=
0x0038
,
ACX_ARP_IP_FILTER
=
0x0039
,
ACX_ROAMING_STATISTICS_TBL
=
0x003B
,
ACX_RATE_POLICY
=
0x003D
,
ACX_CTS_PROTECTION
=
0x003E
,
ACX_SLEEP_AUTH
=
0x003F
,
ACX_PREAMBLE_TYPE
=
0x0040
,
ACX_ERROR_CNT
=
0x0041
,
ACX_IBSS_FILTER
=
0x0044
,
ACX_SERVICE_PERIOD_TIMEOUT
=
0x0045
,
ACX_TSF_INFO
=
0x0046
,
ACX_CONFIG_PS_WMM
=
0x0049
,
ACX_ENABLE_RX_DATA_FILTER
=
0x004A
,
ACX_SET_RX_DATA_FILTER
=
0x004B
,
ACX_GET_DATA_FILTER_STATISTICS
=
0x004C
,
ACX_RX_CONFIG_OPT
=
0x004E
,
ACX_FRAG_CFG
=
0x004F
,
ACX_BET_ENABLE
=
0x0050
,
ACX_RSSI_SNR_TRIGGER
=
0x0051
,
ACX_RSSI_SNR_WEIGHTS
=
0x0052
,
ACX_KEEP_ALIVE_MODE
=
0x0053
,
ACX_SET_KEEP_ALIVE_CONFIG
=
0x0054
,
ACX_BA_SESSION_INIT_POLICY
=
0x0055
,
ACX_BA_SESSION_RX_SETUP
=
0x0056
,
ACX_PEER_HT_CAP
=
0x0057
,
ACX_HT_BSS_OPERATION
=
0x0058
,
ACX_COEX_ACTIVITY
=
0x0059
,
ACX_BURST_MODE
=
0x005C
,
ACX_SET_RATE_MGMT_PARAMS
=
0x005D
,
ACX_SET_RATE_ADAPT_PARAMS
=
0x0060
,
ACX_SET_DCO_ITRIM_PARAMS
=
0x0061
,
ACX_GEN_FW_CMD
=
0x0070
,
ACX_HOST_IF_CFG_BITMAP
=
0x0071
,
ACX_MAX_TX_FAILURE
=
0x0072
,
ACX_UPDATE_INCONNECTION_STA_LIST
=
0x0073
,
DOT11_RX_MSDU_LIFE_TIME
=
0x1004
,
DOT11_CUR_TX_PWR
=
0x100D
,
DOT11_RX_DOT11_MODE
=
0x1012
,
DOT11_RTS_THRESHOLD
=
0x1013
,
DOT11_GROUP_ADDRESS_TBL
=
0x1014
,
ACX_PM_CONFIG
=
0x1016
,
ACX_CONFIG_PS
=
0x1017
,
ACX_CONFIG_HANGOVER
=
0x1018
,
ACX_WAKE_UP_CONDITIONS
=
0x0000
,
ACX_MEM_CFG
=
0x0001
,
ACX_SLOT
=
0x0002
,
ACX_AC_CFG
=
0x0003
,
ACX_MEM_MAP
=
0x0004
,
ACX_AID
=
0x0005
,
ACX_MEDIUM_USAGE
=
0x0006
,
ACX_STATISTICS
=
0x0007
,
ACX_PWR_CONSUMPTION_STATISTICS
=
0x0008
,
ACX_TID_CFG
=
0x0009
,
ACX_PS_RX_STREAMING
=
0x000A
,
ACX_BEACON_FILTER_OPT
=
0x000B
,
ACX_NOISE_HIST
=
0x000C
,
ACX_HDK_VERSION
=
0x000D
,
ACX_PD_THRESHOLD
=
0x000E
,
ACX_TX_CONFIG_OPT
=
0x000F
,
ACX_CCA_THRESHOLD
=
0x0010
,
ACX_EVENT_MBOX_MASK
=
0x0011
,
ACX_CONN_MONIT_PARAMS
=
0x0012
,
ACX_DISABLE_BROADCASTS
=
0x0013
,
ACX_BCN_DTIM_OPTIONS
=
0x0014
,
ACX_SG_ENABLE
=
0x0015
,
ACX_SG_CFG
=
0x0016
,
ACX_FM_COEX_CFG
=
0x0017
,
ACX_BEACON_FILTER_TABLE
=
0x0018
,
ACX_ARP_IP_FILTER
=
0x0019
,
ACX_ROAMING_STATISTICS_TBL
=
0x001A
,
ACX_RATE_POLICY
=
0x001B
,
ACX_CTS_PROTECTION
=
0x001C
,
ACX_SLEEP_AUTH
=
0x001D
,
ACX_PREAMBLE_TYPE
=
0x001E
,
ACX_ERROR_CNT
=
0x001F
,
ACX_IBSS_FILTER
=
0x0020
,
ACX_SERVICE_PERIOD_TIMEOUT
=
0x0021
,
ACX_TSF_INFO
=
0x0022
,
ACX_CONFIG_PS_WMM
=
0x0023
,
ACX_ENABLE_RX_DATA_FILTER
=
0x0024
,
ACX_SET_RX_DATA_FILTER
=
0x0025
,
ACX_GET_DATA_FILTER_STATISTICS
=
0x0026
,
ACX_RX_CONFIG_OPT
=
0x0027
,
ACX_FRAG_CFG
=
0x0028
,
ACX_BET_ENABLE
=
0x0029
,
ACX_RSSI_SNR_TRIGGER
=
0x002A
,
ACX_RSSI_SNR_WEIGHTS
=
0x002B
,
ACX_KEEP_ALIVE_MODE
=
0x002C
,
ACX_SET_KEEP_ALIVE_CONFIG
=
0x002D
,
ACX_BA_SESSION_INIT_POLICY
=
0x002E
,
ACX_BA_SESSION_RX_SETUP
=
0x002F
,
ACX_PEER_HT_CAP
=
0x0030
,
ACX_HT_BSS_OPERATION
=
0x0031
,
ACX_COEX_ACTIVITY
=
0x0032
,
ACX_BURST_MODE
=
0x0033
,
ACX_SET_RATE_MGMT_PARAMS
=
0x0034
,
ACX_GET_RATE_MGMT_PARAMS
=
0x0035
,
ACX_SET_RATE_ADAPT_PARAMS
=
0x0036
,
ACX_SET_DCO_ITRIM_PARAMS
=
0x0037
,
ACX_GEN_FW_CMD
=
0x0038
,
ACX_HOST_IF_CFG_BITMAP
=
0x0039
,
ACX_MAX_TX_FAILURE
=
0x003A
,
ACX_UPDATE_INCONNECTION_STA_LIST
=
0x003B
,
DOT11_RX_MSDU_LIFE_TIME
=
0x003C
,
DOT11_CUR_TX_PWR
=
0x003D
,
DOT11_RTS_THRESHOLD
=
0x003E
,
DOT11_GROUP_ADDRESS_TBL
=
0x003F
,
ACX_PM_CONFIG
=
0x0040
,
ACX_CONFIG_PS
=
0x0041
,
ACX_CONFIG_HANGOVER
=
0x0042
,
ACX_FEATURE_CFG
=
0x0043
,
ACX_PROTECTION_CFG
=
0x0044
,
};
int
wl1271_acx_wake_up_conditions
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
);
struct
wl12xx_vif
*
wlvif
,
u8
wake_up_event
,
u8
listen_interval
);
int
wl1271_acx_sleep_auth
(
struct
wl1271
*
wl
,
u8
sleep_auth
);
int
wl1271_acx_tx_power
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
int
power
);
...
...
@@ -1296,7 +1300,8 @@ int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
struct
wl12xx_vif
*
wlvif
);
int
wl12xx_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
,
u8
peer_hlid
);
int
wl1271_acx_tsf_info
(
struct
wl1271
*
wl
,
u64
*
mactime
);
int
wl12xx_acx_tsf_info
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u64
*
mactime
);
int
wl1271_acx_ps_rx_streaming
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
bool
enable
);
int
wl1271_acx_ap_max_tx_retry
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
);
...
...
drivers/net/wireless/wl12xx/boot.c
View file @
8715d941
...
...
@@ -33,65 +33,6 @@
#include "event.h"
#include "rx.h"
static
struct
wl1271_partition_set
part_table
[
PART_TABLE_LEN
]
=
{
[
PART_DOWN
]
=
{
.
mem
=
{
.
start
=
0x00000000
,
.
size
=
0x000177c0
},
.
reg
=
{
.
start
=
REGISTERS_BASE
,
.
size
=
0x00008800
},
.
mem2
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
.
mem3
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
},
[
PART_WORK
]
=
{
.
mem
=
{
.
start
=
0x00040000
,
.
size
=
0x00014fc0
},
.
reg
=
{
.
start
=
REGISTERS_BASE
,
.
size
=
0x0000a000
},
.
mem2
=
{
.
start
=
0x003004f8
,
.
size
=
0x00000004
},
.
mem3
=
{
.
start
=
0x00040404
,
.
size
=
0x00000000
},
},
[
PART_DRPW
]
=
{
.
mem
=
{
.
start
=
0x00040000
,
.
size
=
0x00014fc0
},
.
reg
=
{
.
start
=
DRPW_BASE
,
.
size
=
0x00006000
},
.
mem2
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
.
mem3
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
}
}
};
static
void
wl1271_boot_set_ecpu_ctrl
(
struct
wl1271
*
wl
,
u32
flag
)
{
u32
cpu_ctrl
;
...
...
@@ -181,13 +122,13 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
return
-
ENOMEM
;
}
memcpy
(
&
partition
,
&
part_table
[
PART_DOWN
],
sizeof
(
partition
));
memcpy
(
&
partition
,
&
wl12xx_
part_table
[
PART_DOWN
],
sizeof
(
partition
));
partition
.
mem
.
start
=
dest
;
wl1271_set_partition
(
wl
,
&
partition
);
/* 10.1 set partition limit and chunk num */
chunk_num
=
0
;
partition_limit
=
part_table
[
PART_DOWN
].
mem
.
size
;
partition_limit
=
wl12xx_
part_table
[
PART_DOWN
].
mem
.
size
;
while
(
chunk_num
<
fw_data_len
/
CHUNK_SIZE
)
{
/* 10.2 update partition, if needed */
...
...
@@ -195,7 +136,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
if
(
addr
>
partition_limit
)
{
addr
=
dest
+
chunk_num
*
CHUNK_SIZE
;
partition_limit
=
chunk_num
*
CHUNK_SIZE
+
part_table
[
PART_DOWN
].
mem
.
size
;
wl12xx_
part_table
[
PART_DOWN
].
mem
.
size
;
partition
.
mem
.
start
=
addr
;
wl1271_set_partition
(
wl
,
&
partition
);
}
...
...
@@ -317,12 +258,12 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
}
/* update current MAC address to NVS */
nvs_ptr
[
11
]
=
wl
->
mac_
addr
[
0
];
nvs_ptr
[
10
]
=
wl
->
mac_
addr
[
1
];
nvs_ptr
[
6
]
=
wl
->
mac_
addr
[
2
];
nvs_ptr
[
5
]
=
wl
->
mac_
addr
[
3
];
nvs_ptr
[
4
]
=
wl
->
mac_
addr
[
4
];
nvs_ptr
[
3
]
=
wl
->
mac_
addr
[
5
];
nvs_ptr
[
11
]
=
wl
->
addresses
[
0
].
addr
[
0
];
nvs_ptr
[
10
]
=
wl
->
addresses
[
0
].
addr
[
1
];
nvs_ptr
[
6
]
=
wl
->
addresses
[
0
].
addr
[
2
];
nvs_ptr
[
5
]
=
wl
->
addresses
[
0
].
addr
[
3
];
nvs_ptr
[
4
]
=
wl
->
addresses
[
0
].
addr
[
4
];
nvs_ptr
[
3
]
=
wl
->
addresses
[
0
].
addr
[
5
];
/*
* Layout before the actual NVS tables:
...
...
@@ -383,7 +324,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
nvs_len
-=
nvs_ptr
-
(
u8
*
)
wl
->
nvs
;
/* Now we must set the partition correctly */
wl1271_set_partition
(
wl
,
&
part_table
[
PART_WORK
]);
wl1271_set_partition
(
wl
,
&
wl12xx_
part_table
[
PART_WORK
]);
/* Copy the NVS tables to a new block to ensure alignment */
nvs_aligned
=
kmemdup
(
nvs_ptr
,
nvs_len
,
GFP_KERNEL
);
...
...
@@ -492,7 +433,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
wl
->
event_box_addr
=
wl1271_read32
(
wl
,
REG_EVENT_MAILBOX_PTR
);
/* set the working partition to its "running" mode offset */
wl1271_set_partition
(
wl
,
&
part_table
[
PART_WORK
]);
wl1271_set_partition
(
wl
,
&
wl12xx_
part_table
[
PART_WORK
]);
wl1271_debug
(
DEBUG_MAILBOX
,
"cmd_box_addr 0x%x event_box_addr 0x%x"
,
wl
->
cmd_box_addr
,
wl
->
event_box_addr
);
...
...
@@ -507,8 +448,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
/* unmask required mbox events */
wl
->
event_mask
=
BSS_LOSE_EVENT_ID
|
SCAN_COMPLETE_EVENT_ID
|
PS_REPORT_EVENT_ID
|
DISCONNECT_EVENT_COMPLETE_ID
|
ROLE_STOP_COMPLETE_EVENT_ID
|
RSSI_SNR_TRIGGER_0_EVENT_ID
|
PSPOLL_DELIVERY_FAILURE_EVENT_ID
|
SOFT_GEMINI_SENSE_EVENT_ID
|
...
...
@@ -547,19 +487,6 @@ static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
return
0
;
}
static
void
wl1271_boot_hw_version
(
struct
wl1271
*
wl
)
{
u32
fuse
;
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fuse
=
wl1271_top_reg_read
(
wl
,
WL128X_REG_FUSE_DATA_2_1
);
else
fuse
=
wl1271_top_reg_read
(
wl
,
WL127X_REG_FUSE_DATA_2_1
);
fuse
=
(
fuse
&
PG_VER_MASK
)
>>
PG_VER_OFFSET
;
wl
->
hw_pg_ver
=
(
s8
)
fuse
;
}
static
int
wl128x_switch_tcxo_to_fref
(
struct
wl1271
*
wl
)
{
u16
spare_reg
;
...
...
@@ -698,7 +625,7 @@ static int wl127x_boot_clk(struct wl1271 *wl)
u32
pause
;
u32
clk
;
if
(
((
wl
->
hw_pg_ver
&
PG_MAJOR_VER_MASK
)
>>
PG_MAJOR_VER_OFFSET
)
<
3
)
if
(
WL127X_PG_GET_MAJOR
(
wl
->
hw_pg_ver
)
<
3
)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
if
(
wl
->
ref_clock
==
CONF_REF_CLK_19_2_E
||
...
...
@@ -753,8 +680,6 @@ int wl1271_load_firmware(struct wl1271 *wl)
u32
tmp
,
clk
;
int
selected_clock
=
-
1
;
wl1271_boot_hw_version
(
wl
);
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
{
ret
=
wl128x_boot_clk
(
wl
,
&
selected_clock
);
if
(
ret
<
0
)
...
...
@@ -769,7 +694,7 @@ int wl1271_load_firmware(struct wl1271 *wl)
wl1271_write32
(
wl
,
WELP_ARM_COMMAND
,
WELP_ARM_COMMAND_VAL
);
udelay
(
500
);
wl1271_set_partition
(
wl
,
&
part_table
[
PART_DRPW
]);
wl1271_set_partition
(
wl
,
&
wl12xx_
part_table
[
PART_DRPW
]);
/* Read-modify-write DRPW_SCRATCH_START register (see next state)
to be used by DRPw FW. The RTRIM value will be added by the FW
...
...
@@ -788,7 +713,7 @@ int wl1271_load_firmware(struct wl1271 *wl)
wl1271_write32
(
wl
,
DRPW_SCRATCH_START
,
clk
);
wl1271_set_partition
(
wl
,
&
part_table
[
PART_WORK
]);
wl1271_set_partition
(
wl
,
&
wl12xx_
part_table
[
PART_WORK
]);
/* Disable interrupts */
wl1271_write32
(
wl
,
ACX_REG_INTERRUPT_MASK
,
WL1271_ACX_INTR_ALL
);
...
...
drivers/net/wireless/wl12xx/boot.h
View file @
8715d941
...
...
@@ -55,16 +55,6 @@ struct wl1271_static_data {
#define OCP_REG_CLK_POLARITY 0x0cb2
#define OCP_REG_CLK_PULL 0x0cb4
#define WL127X_REG_FUSE_DATA_2_1 0x050a
#define WL128X_REG_FUSE_DATA_2_1 0x2152
#define PG_VER_MASK 0x3c
#define PG_VER_OFFSET 2
#define PG_MAJOR_VER_MASK 0x3
#define PG_MAJOR_VER_OFFSET 0x0
#define PG_MINOR_VER_MASK 0xc
#define PG_MINOR_VER_OFFSET 0x2
#define CMD_MBOX_ADDRESS 0x407B4
#define POLARITY_LOW BIT(1)
...
...
drivers/net/wireless/wl12xx/cmd.c
View file @
8715d941
...
...
@@ -566,7 +566,7 @@ static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl,
goto
out_free
;
}
ret
=
wl1271_cmd_wait_for_event
(
wl
,
DISCONNECT_EVENT_COMPLETE
_ID
);
ret
=
wl1271_cmd_wait_for_event
(
wl
,
ROLE_STOP_COMPLETE_EVENT
_ID
);
if
(
ret
<
0
)
{
wl1271_error
(
"cmd role stop dev event completion error"
);
goto
out_free
;
...
...
@@ -715,6 +715,8 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
cmd
->
ap
.
beacon_interval
=
cpu_to_le16
(
wlvif
->
beacon_int
);
cmd
->
ap
.
dtim_interval
=
bss_conf
->
dtim_period
;
cmd
->
ap
.
beacon_expiry
=
WL1271_AP_DEF_BEACON_EXP
;
/* FIXME: Change when adding DFS */
cmd
->
ap
.
reset_tsf
=
1
;
/* By default reset AP TSF */
cmd
->
channel
=
wlvif
->
channel
;
if
(
!
bss_conf
->
hidden_ssid
)
{
...
...
@@ -994,7 +996,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
}
int
wl1271_cmd_ps_mode
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u8
ps_mode
)
u8
ps_mode
,
u16
auto_ps_timeout
)
{
struct
wl1271_cmd_ps_params
*
ps_params
=
NULL
;
int
ret
=
0
;
...
...
@@ -1009,6 +1011,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
ps_params
->
role_id
=
wlvif
->
role_id
;
ps_params
->
ps_mode
=
ps_mode
;
ps_params
->
auto_ps_timeout
=
auto_ps_timeout
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_PS_MODE
,
ps_params
,
sizeof
(
*
ps_params
),
0
);
...
...
@@ -1022,13 +1025,15 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
return
ret
;
}
int
wl1271_cmd_template_set
(
struct
wl1271
*
wl
,
u16
template_id
,
void
*
buf
,
size_t
buf_len
,
int
index
,
u32
rates
)
int
wl1271_cmd_template_set
(
struct
wl1271
*
wl
,
u8
role_id
,
u16
template_id
,
void
*
buf
,
size_t
buf_len
,
int
index
,
u32
rates
)
{
struct
wl1271_cmd_template_set
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd template_set %d"
,
template_id
);
wl1271_debug
(
DEBUG_CMD
,
"cmd template_set %d (role %d)"
,
template_id
,
role_id
);
WARN_ON
(
buf_len
>
WL1271_CMD_TEMPL_MAX_SIZE
);
buf_len
=
min_t
(
size_t
,
buf_len
,
WL1271_CMD_TEMPL_MAX_SIZE
);
...
...
@@ -1039,6 +1044,8 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
goto
out
;
}
/* during initialization wlvif is NULL */
cmd
->
role_id
=
role_id
;
cmd
->
len
=
cpu_to_le16
(
buf_len
);
cmd
->
template_type
=
template_id
;
cmd
->
enabled_rates
=
cpu_to_le32
(
rates
);
...
...
@@ -1082,7 +1089,8 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
ptr
=
skb
->
data
;
}
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_NULL_DATA
,
ptr
,
size
,
0
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_NULL_DATA
,
ptr
,
size
,
0
,
wlvif
->
basic_rate
);
out:
...
...
@@ -1105,7 +1113,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
if
(
!
skb
)
goto
out
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_KLV
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_KLV
,
skb
->
data
,
skb
->
len
,
CMD_TEMPL_KLV_IDX_NULL_DATA
,
wlvif
->
basic_rate
);
...
...
@@ -1130,7 +1138,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if
(
!
skb
)
goto
out
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_PS_POLL
,
skb
->
data
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_PS_POLL
,
skb
->
data
,
skb
->
len
,
0
,
wlvif
->
basic_rate_set
);
out:
...
...
@@ -1138,9 +1147,10 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
return
ret
;
}
int
wl1271_cmd_build_probe_req
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
int
wl12xx_cmd_build_probe_req
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u8
role_id
,
u8
band
,
const
u8
*
ssid
,
size_t
ssid_len
,
const
u8
*
ie
,
size_t
ie_len
,
u8
band
)
const
u8
*
ie
,
size_t
ie_len
)
{
struct
ieee80211_vif
*
vif
=
wl12xx_wlvif_to_vif
(
wlvif
);
struct
sk_buff
*
skb
;
...
...
@@ -1158,10 +1168,12 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
rate
=
wl1271_tx_min_rate_get
(
wl
,
wlvif
->
bitrate_masks
[
band
]);
if
(
band
==
IEEE80211_BAND_2GHZ
)
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
ret
=
wl1271_cmd_template_set
(
wl
,
role_id
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
skb
->
data
,
skb
->
len
,
0
,
rate
);
else
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
ret
=
wl1271_cmd_template_set
(
wl
,
role_id
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
skb
->
data
,
skb
->
len
,
0
,
rate
);
out:
...
...
@@ -1186,10 +1198,12 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
rate
=
wl1271_tx_min_rate_get
(
wl
,
wlvif
->
bitrate_masks
[
wlvif
->
band
]);
if
(
wlvif
->
band
==
IEEE80211_BAND_2GHZ
)
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
skb
->
data
,
skb
->
len
,
0
,
rate
);
else
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
skb
->
data
,
skb
->
len
,
0
,
rate
);
if
(
ret
<
0
)
...
...
@@ -1199,32 +1213,34 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
return
skb
;
}
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
__be32
ip_addr
)
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
)
{
int
ret
;
int
ret
,
extra
;
u16
fc
;
struct
ieee80211_vif
*
vif
=
wl12xx_wlvif_to_vif
(
wlvif
);
struct
wl12xx_arp_rsp_template
tmpl
;
struct
sk_buff
*
skb
;
struct
wl12xx_arp_rsp_template
*
tmpl
;
struct
ieee80211_hdr_3addr
*
hdr
;
struct
arphdr
*
arp_hdr
;
memset
(
&
tmpl
,
0
,
sizeof
(
tmpl
));
skb
=
dev_alloc_skb
(
sizeof
(
*
hdr
)
+
sizeof
(
__le16
)
+
sizeof
(
*
tmpl
)
+
WL1271_EXTRA_SPACE_MAX
);
if
(
!
skb
)
{
wl1271_error
(
"failed to allocate buffer for arp rsp template"
);
return
-
ENOMEM
;
}
/* mac80211 header */
hdr
=
&
tmpl
.
hdr
;
hdr
->
frame_control
=
cpu_to_le16
(
IEEE80211_FTYPE_DATA
|
IEEE80211_STYPE_DATA
|
IEEE80211_FCTL_TODS
);
memcpy
(
hdr
->
addr1
,
vif
->
bss_conf
.
bssid
,
ETH_ALEN
);
memcpy
(
hdr
->
addr2
,
vif
->
addr
,
ETH_ALEN
);
memset
(
hdr
->
addr3
,
0xff
,
ETH_ALEN
);
skb_reserve
(
skb
,
sizeof
(
*
hdr
)
+
WL1271_EXTRA_SPACE_MAX
);
tmpl
=
(
struct
wl12xx_arp_rsp_template
*
)
skb_put
(
skb
,
sizeof
(
*
tmpl
));
memset
(
tmpl
,
0
,
sizeof
(
tmpl
));
/* llc layer */
memcpy
(
tmpl
.
llc_hdr
,
rfc1042_header
,
sizeof
(
rfc1042_header
));
tmpl
.
llc_type
=
cpu_to_be16
(
ETH_P_ARP
);
memcpy
(
tmpl
->
llc_hdr
,
rfc1042_header
,
sizeof
(
rfc1042_header
));
tmpl
->
llc_type
=
cpu_to_be16
(
ETH_P_ARP
);
/* arp header */
arp_hdr
=
&
tmpl
.
arp_hdr
;
arp_hdr
=
&
tmpl
->
arp_hdr
;
arp_hdr
->
ar_hrd
=
cpu_to_be16
(
ARPHRD_ETHER
);
arp_hdr
->
ar_pro
=
cpu_to_be16
(
ETH_P_IP
);
arp_hdr
->
ar_hln
=
ETH_ALEN
;
...
...
@@ -1232,13 +1248,59 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif,
arp_hdr
->
ar_op
=
cpu_to_be16
(
ARPOP_REPLY
);
/* arp payload */
memcpy
(
tmpl
.
sender_hw
,
vif
->
addr
,
ETH_ALEN
);
tmpl
.
sender_ip
=
ip_addr
;
memcpy
(
tmpl
->
sender_hw
,
vif
->
addr
,
ETH_ALEN
);
tmpl
->
sender_ip
=
wlvif
->
ip_addr
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_ARP_RSP
,
&
tmpl
,
sizeof
(
tmpl
),
0
,
wlvif
->
basic_rate
);
/* encryption space */
switch
(
wlvif
->
encryption_type
)
{
case
KEY_TKIP
:
extra
=
WL1271_EXTRA_SPACE_TKIP
;
break
;
case
KEY_AES
:
extra
=
WL1271_EXTRA_SPACE_AES
;
break
;
case
KEY_NONE
:
case
KEY_WEP
:
case
KEY_GEM
:
extra
=
0
;
break
;
default:
wl1271_warning
(
"Unknown encryption type: %d"
,
wlvif
->
encryption_type
);
ret
=
-
EINVAL
;
goto
out
;
}
if
(
extra
)
{
u8
*
space
=
skb_push
(
skb
,
extra
);
memset
(
space
,
0
,
extra
);
}
/* QoS header - BE */
if
(
wlvif
->
sta
.
qos
)
memset
(
skb_push
(
skb
,
sizeof
(
__le16
)),
0
,
sizeof
(
__le16
));
/* mac80211 header */
hdr
=
(
struct
ieee80211_hdr_3addr
*
)
skb_push
(
skb
,
sizeof
(
*
hdr
));
memset
(
hdr
,
0
,
sizeof
(
hdr
));
fc
=
IEEE80211_FTYPE_DATA
|
IEEE80211_FCTL_TODS
;
if
(
wlvif
->
sta
.
qos
)
fc
|=
IEEE80211_STYPE_QOS_DATA
;
else
fc
|=
IEEE80211_STYPE_DATA
;
if
(
wlvif
->
encryption_type
!=
KEY_NONE
)
fc
|=
IEEE80211_FCTL_PROTECTED
;
hdr
->
frame_control
=
cpu_to_le16
(
fc
);
memcpy
(
hdr
->
addr1
,
vif
->
bss_conf
.
bssid
,
ETH_ALEN
);
memcpy
(
hdr
->
addr2
,
vif
->
addr
,
ETH_ALEN
);
memset
(
hdr
->
addr3
,
0xff
,
ETH_ALEN
);
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_ARP_RSP
,
skb
->
data
,
skb
->
len
,
0
,
wlvif
->
basic_rate
);
out:
dev_kfree_skb
(
skb
);
return
ret
;
}
...
...
@@ -1260,7 +1322,8 @@ int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif)
/* FIXME: not sure what priority to use here */
template
.
qos_ctrl
=
cpu_to_le16
(
0
);
return
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_QOS_NULL_DATA
,
&
template
,
return
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_QOS_NULL_DATA
,
&
template
,
sizeof
(
template
),
0
,
wlvif
->
basic_rate
);
}
...
...
@@ -1744,6 +1807,7 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id)
}
int
wl12xx_cmd_channel_switch
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
ieee80211_channel_switch
*
ch_switch
)
{
struct
wl12xx_cmd_channel_switch
*
cmd
;
...
...
@@ -1757,10 +1821,13 @@ int wl12xx_cmd_channel_switch(struct wl1271 *wl,
goto
out
;
}
cmd
->
role_id
=
wlvif
->
role_id
;
cmd
->
channel
=
ch_switch
->
channel
->
hw_value
;
cmd
->
switch_time
=
ch_switch
->
count
;
cmd
->
tx_suspend
=
ch_switch
->
block_tx
;
cmd
->
flush
=
0
;
/* this value is ignored by the FW */
cmd
->
stop_tx
=
ch_switch
->
block_tx
;
/* FIXME: control from mac80211 in the future */
cmd
->
post_switch_tx_disable
=
0
;
/* Enable TX on the target channel */
ret
=
wl1271_cmd_send
(
wl
,
CMD_CHANNEL_SWITCH
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
...
...
drivers/net/wireless/wl12xx/cmd.h
View file @
8715d941
...
...
@@ -51,22 +51,23 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
int
wl1271_cmd_configure
(
struct
wl1271
*
wl
,
u16
id
,
void
*
buf
,
size_t
len
);
int
wl1271_cmd_data_path
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_cmd_ps_mode
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u8
ps_mode
);
u8
ps_mode
,
u16
auto_ps_timeout
);
int
wl1271_cmd_read_memory
(
struct
wl1271
*
wl
,
u32
addr
,
void
*
answer
,
size_t
len
);
int
wl1271_cmd_template_set
(
struct
wl1271
*
wl
,
u16
template_id
,
void
*
buf
,
size_t
buf_len
,
int
index
,
u32
rates
);
int
wl1271_cmd_template_set
(
struct
wl1271
*
wl
,
u8
role_id
,
u16
template_id
,
void
*
buf
,
size_t
buf_len
,
int
index
,
u32
rates
);
int
wl12xx_cmd_build_null_data
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
);
int
wl1271_cmd_build_ps_poll
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u16
aid
);
int
wl1271_cmd_build_probe_req
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
int
wl12xx_cmd_build_probe_req
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u8
role_id
,
u8
band
,
const
u8
*
ssid
,
size_t
ssid_len
,
const
u8
*
ie
,
size_t
ie_len
,
u8
band
);
const
u8
*
ie
,
size_t
ie_len
);
struct
sk_buff
*
wl1271_cmd_build_ap_probe_req
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
sk_buff
*
skb
);
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
__be32
ip_addr
);
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
);
int
wl1271_build_qos_null_data
(
struct
wl1271
*
wl
,
struct
ieee80211_vif
*
vif
);
int
wl12xx_cmd_build_klv_null_data
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
);
...
...
@@ -89,6 +90,7 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl);
int
wl12xx_cmd_start_fwlog
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_stop_fwlog
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_channel_switch
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
ieee80211_channel_switch
*
ch_switch
);
int
wl12xx_cmd_stop_channel_switch
(
struct
wl1271
*
wl
);
int
wl12xx_allocate_link
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
...
...
@@ -96,62 +98,65 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
void
wl12xx_free_link
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
u8
*
hlid
);
enum
wl1271_commands
{
CMD_INTERROGATE
=
1
,
/*use this to read information elements
*/
CMD_CONFIGURE
=
2
,
/*use this to write information elements
*/
CMD_ENABLE_RX
=
3
,
CMD_ENABLE_TX
=
4
,
CMD_DISABLE_RX
=
5
,
CMD_DISABLE_TX
=
6
,
CMD_SCAN
=
8
,
CMD_STOP_SCAN
=
9
,
CMD_SET_KEYS
=
12
,
CMD_READ_MEMORY
=
13
,
CMD_WRITE_MEMORY
=
14
,
CMD_SET_TEMPLATE
=
19
,
CMD_TEST
=
2
3
,
CMD_NOISE_HIST
=
28
,
CMD_QUIET_ELEMENT_SET_STATE
=
29
,
CMD_SET_BCN_MODE
=
33
,
CMD_MEASUREMENT
=
34
,
CMD_
STOP_MEASUREMENT
=
35
,
CMD_S
ET_PS_MODE
=
37
,
CMD_
CHANNEL_SWITCH
=
38
,
CMD_
STOP_CHANNEL_SWICTH
=
39
,
CMD_
AP_DISCOVERY
=
40
,
CMD_
STOP_AP_DISCOVERY
=
41
,
CMD_
HEALTH_CHECK
=
45
,
CMD_
DEBUG
=
46
,
CMD_
TRIGGER_SCAN_TO
=
47
,
CMD_
CONNECTION_SCAN_CFG
=
48
,
CMD_CONNECTION_SCAN_
SSID_CFG
=
49
,
CMD_
START_PERIODIC_SCAN
=
50
,
CMD_ST
OP_PERIODIC_SCAN
=
51
,
CMD_S
ET_PEER_STATE
=
52
,
CMD_
REMAIN_ON_CHANNEL
=
53
,
CMD_
CANCEL_REMAIN_ON_CHANNEL
=
54
,
CMD_CONFIG_FWLOGGER
=
55
,
CMD_START_FWLOGGER
=
56
,
CMD_STOP_FWLOGGER
=
57
,
/* A
P
commands */
CMD_ADD_PEER
=
62
,
CMD_REMOVE_PEER
=
63
,
CMD_INTERROGATE
=
1
,
/* use this to read information elements
*/
CMD_CONFIGURE
=
2
,
/* use this to write information elements
*/
CMD_ENABLE_RX
=
3
,
CMD_ENABLE_TX
=
4
,
CMD_DISABLE_RX
=
5
,
CMD_DISABLE_TX
=
6
,
CMD_SCAN
=
7
,
CMD_STOP_SCAN
=
8
,
CMD_SET_KEYS
=
9
,
CMD_READ_MEMORY
=
10
,
CMD_WRITE_MEMORY
=
11
,
CMD_SET_TEMPLATE
=
12
,
CMD_TEST
=
1
3
,
CMD_NOISE_HIST
=
14
,
CMD_QUIET_ELEMENT_SET_STATE
=
15
,
CMD_SET_BCN_MODE
=
16
,
CMD_
MEASUREMENT
=
17
,
CMD_S
TOP_MEASUREMENT
=
18
,
CMD_
SET_PS_MODE
=
19
,
CMD_
CHANNEL_SWITCH
=
20
,
CMD_
STOP_CHANNEL_SWICTH
=
21
,
CMD_
AP_DISCOVERY
=
22
,
CMD_
STOP_AP_DISCOVERY
=
23
,
CMD_
HEALTH_CHECK
=
24
,
CMD_
DEBUG
=
25
,
CMD_
TRIGGER_SCAN_TO
=
26
,
CMD_CONNECTION_SCAN_
CFG
=
27
,
CMD_
CONNECTION_SCAN_SSID_CFG
=
28
,
CMD_ST
ART_PERIODIC_SCAN
=
29
,
CMD_S
TOP_PERIODIC_SCAN
=
30
,
CMD_
SET_PEER_STATE
=
31
,
CMD_
REMAIN_ON_CHANNEL
=
32
,
CMD_CANCEL_REMAIN_ON_CHANNEL
=
33
,
CMD_CONFIG_FWLOGGER
=
34
,
CMD_START_FWLOGGER
=
35
,
CMD_STOP_FWLOGGER
=
36
,
/* A
ccess point
commands */
CMD_ADD_PEER
=
37
,
CMD_REMOVE_PEER
=
38
,
/* Role API */
CMD_ROLE_ENABLE
=
70
,
CMD_ROLE_DISABLE
=
71
,
CMD_ROLE_START
=
72
,
CMD_ROLE_STOP
=
73
,
CMD_ROLE_ENABLE
=
39
,
CMD_ROLE_DISABLE
=
40
,
CMD_ROLE_START
=
41
,
CMD_ROLE_STOP
=
42
,
/* WIFI Direct */
CMD_WFD_START_DISCOVERY
=
80
,
CMD_WFD_STOP_DISCOVERY
=
81
,
CMD_WFD_ATTRIBUTE_CONFIG
=
82
,
/* DFS */
CMD_START_RADAR_DETECTION
=
43
,
CMD_STOP_RADAR_DETECTION
=
44
,
CMD_NOP
=
100
,
/* WIFI Direct */
CMD_WFD_START_DISCOVERY
=
45
,
CMD_WFD_STOP_DISCOVERY
=
46
,
CMD_WFD_ATTRIBUTE_CONFIG
=
47
,
CMD_NOP
=
48
,
CMD_LAST_COMMAND
,
NUM_COMMANDS
,
MAX_COMMAND_ID
=
0xFFFF
,
};
...
...
@@ -191,7 +196,7 @@ enum cmd_templ {
/* unit ms */
#define WL1271_COMMAND_TIMEOUT 2000
#define WL1271_CMD_TEMPL_DFLT_SIZE 252
#define WL1271_CMD_TEMPL_MAX_SIZE 5
48
#define WL1271_CMD_TEMPL_MAX_SIZE 5
12
#define WL1271_EVENT_TIMEOUT 750
struct
wl1271_cmd_header
{
...
...
@@ -339,7 +344,9 @@ struct wl12xx_cmd_role_start {
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
padding_1
[
5
];
u8
reset_tsf
;
u8
padding_1
[
4
];
}
__packed
ap
;
};
}
__packed
;
...
...
@@ -364,14 +371,18 @@ struct cmd_enabledisable_path {
struct
wl1271_cmd_template_set
{
struct
wl1271_cmd_header
header
;
__le16
len
;
u8
role_id
;
u8
template_type
;
__le16
len
;
u8
index
;
/* relevant only for KLV_TEMPLATE type */
u8
padding
[
3
];
__le32
enabled_rates
;
u8
short_retry_limit
;
u8
long_retry_limit
;
u8
aflags
;
u8
reserved
;
u8
template_data
[
WL1271_CMD_TEMPL_MAX_SIZE
];
}
__packed
;
...
...
@@ -388,6 +399,7 @@ struct wl1271_tim {
}
__packed
;
enum
wl1271_cmd_ps_mode
{
STATION_AUTO_PS_MODE
,
/* Dynamic Power Save */
STATION_ACTIVE_MODE
,
STATION_POWER_SAVE_MODE
};
...
...
@@ -397,7 +409,7 @@ struct wl1271_cmd_ps_params {
u8
role_id
;
u8
ps_mode
;
/* STATION_* */
u
8
padding
[
2
]
;
u
16
auto_ps_timeout
;
}
__packed
;
/* HW encryption keys */
...
...
@@ -695,14 +707,18 @@ struct wl12xx_cmd_stop_fwlog {
struct
wl12xx_cmd_channel_switch
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
/* The new serving channel */
u8
channel
;
/* Relative time of the serving channel switch in TBTT units */
u8
switch_time
;
/* 1: Suspend TX till switch time; 0: Do not suspend TX */
u8
tx_suspend
;
/* 1: Flush TX at switch time; 0: Do not flush */
u8
flush
;
/* Stop the role TX, should expect it after radar detection */
u8
stop_tx
;
/* The target channel tx status 1-stopped 0-open*/
u8
post_switch_tx_disable
;
u8
padding
[
3
];
}
__packed
;
struct
wl12xx_cmd_stop_channel_switch
{
...
...
drivers/net/wireless/wl12xx/conf.h
View file @
8715d941
...
...
@@ -66,7 +66,8 @@ enum {
};
enum
{
CONF_HW_RXTX_RATE_MCS7
=
0
,
CONF_HW_RXTX_RATE_MCS7_SGI
=
0
,
CONF_HW_RXTX_RATE_MCS7
,
CONF_HW_RXTX_RATE_MCS6
,
CONF_HW_RXTX_RATE_MCS5
,
CONF_HW_RXTX_RATE_MCS4
,
...
...
@@ -91,6 +92,10 @@ enum {
CONF_HW_RXTX_RATE_UNSUPPORTED
=
0xff
};
/* Rates between and including these are MCS rates */
#define CONF_HW_RXTX_RATE_MCS_MIN CONF_HW_RXTX_RATE_MCS7_SGI
#define CONF_HW_RXTX_RATE_MCS_MAX CONF_HW_RXTX_RATE_MCS0
enum
{
CONF_SG_DISABLE
=
0
,
CONF_SG_PROTECTIVE
,
...
...
@@ -312,6 +317,10 @@ enum {
CONF_AP_BT_ACL_VAL_BT_SERVE_TIME
,
CONF_AP_BT_ACL_VAL_WL_SERVE_TIME
,
/* CTS Diluting params */
CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH
,
CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER
,
CONF_SG_TEMP_PARAM_1
,
CONF_SG_TEMP_PARAM_2
,
CONF_SG_TEMP_PARAM_3
,
...
...
@@ -809,6 +818,19 @@ struct conf_conn_settings {
*/
u8
listen_interval
;
/*
* Firmware wakeup conditions during suspend
* Range: CONF_WAKE_UP_EVENT_*
*/
u8
suspend_wake_up_event
;
/*
* Listen interval during suspend.
* Currently will be in DTIMs (1-10)
*
*/
u8
suspend_listen_interval
;
/*
* Enable or disable the beacon filtering.
*
...
...
@@ -867,13 +889,6 @@ struct conf_conn_settings {
*/
u8
ps_poll_threshold
;
/*
* PS Poll failure recovery ACTIVE period length
*
* Range: u32 (ms)
*/
u32
ps_poll_recovery_period
;
/*
* Configuration of signal average weights.
*/
...
...
@@ -921,6 +936,18 @@ struct conf_conn_settings {
*/
u8
psm_entry_nullfunc_retries
;
/*
* Specifies the dynamic PS timeout in ms that will be used
* by the FW when in AUTO_PS mode
*/
u16
dynamic_ps_timeout
;
/*
* Specifies whether dynamic PS should be disabled and PSM forced.
* This is required for certain WiFi certification tests.
*/
u8
forced_ps
;
/*
*
* Specifies the interval of the connection keep-alive null-func
...
...
@@ -1055,6 +1082,14 @@ struct conf_scan_settings {
*/
u16
num_probe_reqs
;
/*
* Scan trigger (split scan) timeout. The FW will split the scan
* operation into slices of the given time and allow the FW to schedule
* other tasks in between.
*
* Range: u32 Microsecs
*/
u32
split_scan_timeout
;
};
struct
conf_sched_scan_settings
{
...
...
drivers/net/wireless/wl12xx/debug.h
View file @
8715d941
...
...
@@ -51,6 +51,7 @@ enum {
DEBUG_FILTERS
=
BIT
(
15
),
DEBUG_ADHOC
=
BIT
(
16
),
DEBUG_AP
=
BIT
(
17
),
DEBUG_PROBE
=
BIT
(
18
),
DEBUG_MASTER
=
(
DEBUG_ADHOC
|
DEBUG_AP
),
DEBUG_ALL
=
~
0
,
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
View file @
8715d941
...
...
@@ -113,7 +113,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out
;
if
(
wl
->
state
==
WL1271_STATE_ON
&&
if
(
wl
->
state
==
WL1271_STATE_ON
&&
!
wl
->
plt
&&
time_after
(
jiffies
,
wl
->
stats
.
fw_stats_update
+
msecs_to_jiffies
(
WL1271_DEBUGFS_STATS_LIFETIME
)))
{
wl1271_acx_statistics
(
wl
,
wl
->
stats
.
fw_stats
);
...
...
@@ -312,6 +312,181 @@ static const struct file_operations start_recovery_ops = {
.
llseek
=
default_llseek
,
};
static
ssize_t
dynamic_ps_timeout_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
wl
->
conf
.
conn
.
dynamic_ps_timeout
);
}
static
ssize_t
dynamic_ps_timeout_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
struct
wl12xx_vif
*
wlvif
;
unsigned
long
value
;
int
ret
;
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in dynamic_ps"
);
return
-
EINVAL
;
}
if
(
value
<
1
||
value
>
65535
)
{
wl1271_warning
(
"dyanmic_ps_timeout is not in valid range"
);
return
-
ERANGE
;
}
mutex_lock
(
&
wl
->
mutex
);
wl
->
conf
.
conn
.
dynamic_ps_timeout
=
value
;
if
(
wl
->
state
==
WL1271_STATE_OFF
)
goto
out
;
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
/* In case we're already in PSM, trigger it again to set new timeout
* immediately without waiting for re-association
*/
wl12xx_for_each_wlvif_sta
(
wl
,
wlvif
)
{
if
(
test_bit
(
WLVIF_FLAG_IN_PS
,
&
wlvif
->
flags
))
wl1271_ps_set_mode
(
wl
,
wlvif
,
STATION_AUTO_PS_MODE
);
}
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
dynamic_ps_timeout_ops
=
{
.
read
=
dynamic_ps_timeout_read
,
.
write
=
dynamic_ps_timeout_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
forced_ps_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
wl
->
conf
.
conn
.
forced_ps
);
}
static
ssize_t
forced_ps_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
struct
wl12xx_vif
*
wlvif
;
unsigned
long
value
;
int
ret
,
ps_mode
;
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in forced_ps"
);
return
-
EINVAL
;
}
if
(
value
!=
1
&&
value
!=
0
)
{
wl1271_warning
(
"forced_ps should be either 0 or 1"
);
return
-
ERANGE
;
}
mutex_lock
(
&
wl
->
mutex
);
if
(
wl
->
conf
.
conn
.
forced_ps
==
value
)
goto
out
;
wl
->
conf
.
conn
.
forced_ps
=
value
;
if
(
wl
->
state
==
WL1271_STATE_OFF
)
goto
out
;
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
/* In case we're already in PSM, trigger it again to switch mode
* immediately without waiting for re-association
*/
ps_mode
=
value
?
STATION_POWER_SAVE_MODE
:
STATION_AUTO_PS_MODE
;
wl12xx_for_each_wlvif_sta
(
wl
,
wlvif
)
{
if
(
test_bit
(
WLVIF_FLAG_IN_PS
,
&
wlvif
->
flags
))
wl1271_ps_set_mode
(
wl
,
wlvif
,
ps_mode
);
}
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
forced_ps_ops
=
{
.
read
=
forced_ps_read
,
.
write
=
forced_ps_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
split_scan_timeout_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
wl
->
conf
.
scan
.
split_scan_timeout
/
1000
);
}
static
ssize_t
split_scan_timeout_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
unsigned
long
value
;
int
ret
;
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in split_scan_timeout"
);
return
-
EINVAL
;
}
if
(
value
==
0
)
wl1271_info
(
"split scan will be disabled"
);
mutex_lock
(
&
wl
->
mutex
);
wl
->
conf
.
scan
.
split_scan_timeout
=
value
*
1000
;
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
split_scan_timeout_ops
=
{
.
read
=
split_scan_timeout_read
,
.
write
=
split_scan_timeout_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
driver_state_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
...
...
@@ -446,6 +621,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
VIF_STATE_PRINT_INT
(
sta
.
basic_rate_idx
);
VIF_STATE_PRINT_INT
(
sta
.
ap_rate_idx
);
VIF_STATE_PRINT_INT
(
sta
.
p2p_rate_idx
);
VIF_STATE_PRINT_INT
(
sta
.
qos
);
}
else
{
VIF_STATE_PRINT_INT
(
ap
.
global_hlid
);
VIF_STATE_PRINT_INT
(
ap
.
bcast_hlid
);
...
...
@@ -471,7 +647,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
VIF_STATE_PRINT_INT
(
default_key
);
VIF_STATE_PRINT_INT
(
aid
);
VIF_STATE_PRINT_INT
(
session_counter
);
VIF_STATE_PRINT_INT
(
ps_poll_failures
);
VIF_STATE_PRINT_INT
(
psm_entry_retry
);
VIF_STATE_PRINT_INT
(
power_level
);
VIF_STATE_PRINT_INT
(
rssi_thold
);
...
...
@@ -562,6 +737,64 @@ static const struct file_operations dtim_interval_ops = {
.
llseek
=
default_llseek
,
};
static
ssize_t
suspend_dtim_interval_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
u8
value
;
if
(
wl
->
conf
.
conn
.
suspend_wake_up_event
==
CONF_WAKE_UP_EVENT_DTIM
||
wl
->
conf
.
conn
.
suspend_wake_up_event
==
CONF_WAKE_UP_EVENT_N_DTIM
)
value
=
wl
->
conf
.
conn
.
suspend_listen_interval
;
else
value
=
0
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
value
);
}
static
ssize_t
suspend_dtim_interval_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
unsigned
long
value
;
int
ret
;
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for suspend_dtim_interval"
);
return
-
EINVAL
;
}
if
(
value
<
1
||
value
>
10
)
{
wl1271_warning
(
"suspend_dtim value is not in valid range"
);
return
-
ERANGE
;
}
mutex_lock
(
&
wl
->
mutex
);
wl
->
conf
.
conn
.
suspend_listen_interval
=
value
;
/* for some reason there are different event types for 1 and >1 */
if
(
value
==
1
)
wl
->
conf
.
conn
.
suspend_wake_up_event
=
CONF_WAKE_UP_EVENT_DTIM
;
else
wl
->
conf
.
conn
.
suspend_wake_up_event
=
CONF_WAKE_UP_EVENT_N_DTIM
;
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
suspend_dtim_interval_ops
=
{
.
read
=
suspend_dtim_interval_read
,
.
write
=
suspend_dtim_interval_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
beacon_interval_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
...
...
@@ -886,8 +1119,12 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD
(
driver_state
,
rootdir
);
DEBUGFS_ADD
(
vifs_state
,
rootdir
);
DEBUGFS_ADD
(
dtim_interval
,
rootdir
);
DEBUGFS_ADD
(
suspend_dtim_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_filtering
,
rootdir
);
DEBUGFS_ADD
(
dynamic_ps_timeout
,
rootdir
);
DEBUGFS_ADD
(
forced_ps
,
rootdir
);
DEBUGFS_ADD
(
split_scan_timeout
,
rootdir
);
streaming
=
debugfs_create_dir
(
"rx_streaming"
,
rootdir
);
if
(
!
streaming
||
IS_ERR
(
streaming
))
...
...
drivers/net/wireless/wl12xx/event.c
View file @
8715d941
...
...
@@ -30,133 +30,6 @@
#include "scan.h"
#include "wl12xx_80211.h"
void
wl1271_pspoll_work
(
struct
work_struct
*
work
)
{
struct
ieee80211_vif
*
vif
;
struct
wl12xx_vif
*
wlvif
;
struct
delayed_work
*
dwork
;
struct
wl1271
*
wl
;
int
ret
;
dwork
=
container_of
(
work
,
struct
delayed_work
,
work
);
wlvif
=
container_of
(
dwork
,
struct
wl12xx_vif
,
pspoll_work
);
vif
=
container_of
((
void
*
)
wlvif
,
struct
ieee80211_vif
,
drv_priv
);
wl
=
wlvif
->
wl
;
wl1271_debug
(
DEBUG_EVENT
,
"pspoll work"
);
mutex_lock
(
&
wl
->
mutex
);
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_OFF
))
goto
out
;
if
(
!
test_and_clear_bit
(
WLVIF_FLAG_PSPOLL_FAILURE
,
&
wlvif
->
flags
))
goto
out
;
if
(
!
test_bit
(
WLVIF_FLAG_STA_ASSOCIATED
,
&
wlvif
->
flags
))
goto
out
;
/*
* if we end up here, then we were in powersave when the pspoll
* 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
,
wlvif
,
STATION_POWER_SAVE_MODE
,
wlvif
->
basic_rate
,
true
);
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
};
static
void
wl1271_event_pspoll_delivery_fail
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
)
{
int
delay
=
wl
->
conf
.
conn
.
ps_poll_recovery_period
;
int
ret
;
wlvif
->
ps_poll_failures
++
;
if
(
wlvif
->
ps_poll_failures
==
1
)
wl1271_info
(
"AP with dysfunctional ps-poll, "
"trying to work around it."
);
/* force active mode receive data from the AP */
if
(
test_bit
(
WLVIF_FLAG_PSM
,
&
wlvif
->
flags
))
{
ret
=
wl1271_ps_set_mode
(
wl
,
wlvif
,
STATION_ACTIVE_MODE
,
wlvif
->
basic_rate
,
true
);
if
(
ret
<
0
)
return
;
set_bit
(
WLVIF_FLAG_PSPOLL_FAILURE
,
&
wlvif
->
flags
);
ieee80211_queue_delayed_work
(
wl
->
hw
,
&
wlvif
->
pspoll_work
,
msecs_to_jiffies
(
delay
));
}
/*
* If already in active mode, lets we should be getting data from
* the AP right away. If we enter PSM too fast after this, and data
* remains on the AP, we will get another event like this, and we'll
* go into active once more.
*/
}
static
int
wl1271_event_ps_report
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
event_mailbox
*
mbox
,
bool
*
beacon_loss
)
{
int
ret
=
0
;
u32
total_retries
=
wl
->
conf
.
conn
.
psm_entry_retries
;
wl1271_debug
(
DEBUG_EVENT
,
"ps_status: 0x%x"
,
mbox
->
ps_status
);
switch
(
mbox
->
ps_status
)
{
case
EVENT_ENTER_POWER_SAVE_FAIL
:
wl1271_debug
(
DEBUG_PSM
,
"PSM entry failed"
);
if
(
!
test_bit
(
WLVIF_FLAG_PSM
,
&
wlvif
->
flags
))
{
/* remain in active mode */
wlvif
->
psm_entry_retry
=
0
;
break
;
}
if
(
wlvif
->
psm_entry_retry
<
total_retries
)
{
wlvif
->
psm_entry_retry
++
;
ret
=
wl1271_ps_set_mode
(
wl
,
wlvif
,
STATION_POWER_SAVE_MODE
,
wlvif
->
basic_rate
,
true
);
}
else
{
wl1271_info
(
"No ack to nullfunc from AP."
);
wlvif
->
psm_entry_retry
=
0
;
*
beacon_loss
=
true
;
}
break
;
case
EVENT_ENTER_POWER_SAVE_SUCCESS
:
wlvif
->
psm_entry_retry
=
0
;
/*
* BET has only a minor effect in 5GHz and masks
* channel switch IEs, so we only enable BET on 2.4GHz
*/
if
(
wlvif
->
band
==
IEEE80211_BAND_2GHZ
)
/* enable beacon early termination */
ret
=
wl1271_acx_bet_enable
(
wl
,
wlvif
,
true
);
if
(
wlvif
->
ps_compl
)
{
complete
(
wlvif
->
ps_compl
);
wlvif
->
ps_compl
=
NULL
;
}
break
;
default:
break
;
}
return
ret
;
}
static
void
wl1271_event_rssi_trigger
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
event_mailbox
*
mbox
)
...
...
@@ -205,21 +78,13 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
static
void
wl12xx_event_soft_gemini_sense
(
struct
wl1271
*
wl
,
u8
enable
)
{
struct
ieee80211_vif
*
vif
;
struct
wl12xx_vif
*
wlvif
;
if
(
enable
)
{
/* disable dynamic PS when requested by the firmware */
wl12xx_for_each_wlvif_sta
(
wl
,
wlvif
)
{
vif
=
wl12xx_wlvif_to_vif
(
wlvif
);
ieee80211_disable_dyn_ps
(
vif
);
}
set_bit
(
WL1271_FLAG_SOFT_GEMINI
,
&
wl
->
flags
);
}
else
{
clear_bit
(
WL1271_FLAG_SOFT_GEMINI
,
&
wl
->
flags
);
wl12xx_for_each_wlvif_sta
(
wl
,
wlvif
)
{
vif
=
wl12xx_wlvif_to_vif
(
wlvif
);
ieee80211_enable_dyn_ps
(
vif
);
wl1271_recalc_rx_streaming
(
wl
,
wlvif
);
}
}
...
...
@@ -237,7 +102,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
{
struct
ieee80211_vif
*
vif
;
struct
wl12xx_vif
*
wlvif
;
int
ret
;
u32
vector
;
bool
beacon_loss
=
false
;
bool
disconnect_sta
=
false
;
...
...
@@ -293,21 +157,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
beacon_loss
=
true
;
}
if
(
vector
&
PS_REPORT_EVENT_ID
)
{
wl1271_debug
(
DEBUG_EVENT
,
"PS_REPORT_EVENT"
);
wl12xx_for_each_wlvif_sta
(
wl
,
wlvif
)
{
ret
=
wl1271_event_ps_report
(
wl
,
wlvif
,
mbox
,
&
beacon_loss
);
if
(
ret
<
0
)
return
ret
;
}
}
if
(
vector
&
PSPOLL_DELIVERY_FAILURE_EVENT_ID
)
wl12xx_for_each_wlvif_sta
(
wl
,
wlvif
)
{
wl1271_event_pspoll_delivery_fail
(
wl
,
wlvif
);
}
if
(
vector
&
RSSI_SNR_TRIGGER_0_EVENT_ID
)
{
/* TODO: check actual multi-role support */
wl1271_debug
(
DEBUG_EVENT
,
"RSSI_SNR_TRIGGER_0_EVENT"
);
...
...
@@ -344,7 +193,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
/* TODO: configure only the relevant vif */
wl12xx_for_each_wlvif_sta
(
wl
,
wlvif
)
{
struct
ieee80211_vif
*
vif
=
wl12xx_wlvif_to_vif
(
wlvif
);
bool
success
;
if
(
!
test_and_clear_bit
(
WLVIF_FLAG_CS_PROGRESS
,
...
...
@@ -352,6 +200,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
continue
;
success
=
mbox
->
channel_switch_status
?
false
:
true
;
vif
=
wl12xx_wlvif_to_vif
(
wlvif
);
ieee80211_chswitch_done
(
vif
,
success
);
}
}
...
...
drivers/net/wireless/wl12xx/event.h
View file @
8715d941
...
...
@@ -51,10 +51,10 @@ enum {
SCAN_COMPLETE_EVENT_ID
=
BIT
(
10
),
WFD_DISCOVERY_COMPLETE_EVENT_ID
=
BIT
(
11
),
AP_DISCOVERY_COMPLETE_EVENT_ID
=
BIT
(
12
),
PS_REPORT_EVENT_ID
=
BIT
(
13
),
RESERVED1
=
BIT
(
13
),
PSPOLL_DELIVERY_FAILURE_EVENT_ID
=
BIT
(
14
),
DISCONNECT_EVENT_COMPLETE
_ID
=
BIT
(
15
),
/* BIT(16) is reserved */
ROLE_STOP_COMPLETE_EVENT
_ID
=
BIT
(
15
),
RADAR_DETECTED_EVENT_ID
=
BIT
(
16
),
CHANNEL_SWITCH_COMPLETE_EVENT_ID
=
BIT
(
17
),
BSS_LOSE_EVENT_ID
=
BIT
(
18
),
REGAINED_BSS_EVENT_ID
=
BIT
(
19
),
...
...
@@ -94,9 +94,9 @@ struct event_mailbox {
u8
soft_gemini_sense_info
;
u8
soft_gemini_protective_info
;
s8
rssi_snr_trigger_metric
[
NUM_OF_RSSI_SNR_TRIGGERS
];
u8
chan
nel_switch_status
;
u8
chan
ge_auto_mode_timeout
;
u8
scheduled_scan_status
;
u8
ps_status
;
u8
reserved4
;
/* tuned channel (roc) */
u8
roc_channel
;
...
...
@@ -119,17 +119,21 @@ struct event_mailbox {
u8
rx_ba_allowed
;
u8
reserved_6
[
2
];
/* Channel switch results */
u8
channel_switch_role_id
;
u8
channel_switch_status
;
u8
reserved_7
[
2
];
u8
ps_poll_delivery_failure_role_ids
;
u8
stopped_role_ids
;
u8
started_role_ids
;
u8
change_auto_mode_timeout
;
u8
reserved_
7
[
12
];
u8
reserved_
8
[
9
];
}
__packed
;
int
wl1271_event_unmask
(
struct
wl1271
*
wl
);
void
wl1271_event_mbox_config
(
struct
wl1271
*
wl
);
int
wl1271_event_handle
(
struct
wl1271
*
wl
,
u8
mbox
);
void
wl1271_pspoll_work
(
struct
work_struct
*
work
);
#endif
drivers/net/wireless/wl12xx/init.c
View file @
8715d941
...
...
@@ -37,54 +37,64 @@
int
wl1271_init_templates_config
(
struct
wl1271
*
wl
)
{
int
ret
,
i
;
size_t
max_size
;
/* send empty templates for fw memory reservation */
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
NULL
,
WL1271_CMD_TEMPL_DFLT_SIZE
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
NULL
,
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
NULL
,
WL1271_CMD_TEMPL_DFLT_SIZE
,
0
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_CFG_PROBE_REQ_5
,
NULL
,
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_NULL_DATA
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_NULL_DATA
,
NULL
,
sizeof
(
struct
wl12xx_null_data_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_PS_POLL
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_PS_POLL
,
NULL
,
sizeof
(
struct
wl12xx_ps_poll_template
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_QOS_NULL_DATA
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_QOS_NULL_DATA
,
NULL
,
sizeof
(
struct
ieee80211_qos_hdr
),
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_PROBE_RESPONSE
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_PROBE_RESPONSE
,
NULL
,
WL1271_CMD_TEMPL_DFLT_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_BEACON
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_BEACON
,
NULL
,
WL1271_CMD_TEMPL_DFLT_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_ARP_RSP
,
NULL
,
sizeof
(
struct
wl12xx_arp_rsp_template
),
max_size
=
sizeof
(
struct
wl12xx_arp_rsp_template
)
+
WL1271_EXTRA_SPACE_MAX
;
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_ARP_RSP
,
NULL
,
max_size
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -93,19 +103,22 @@ int wl1271_init_templates_config(struct wl1271 *wl)
* Put very large empty placeholders for all templates. These
* reserve memory for later.
*/
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
NULL
,
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_AP_BEACON
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_AP_BEACON
,
NULL
,
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_DEAUTH_AP
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_DEAUTH_AP
,
NULL
,
sizeof
(
struct
wl12xx_disconn_template
),
0
,
WL1271_RATE_AUTOMATIC
);
...
...
@@ -113,7 +126,8 @@ int wl1271_init_templates_config(struct wl1271 *wl)
return
ret
;
for
(
i
=
0
;
i
<
CMD_TEMPL_KLV_IDX_MAX
;
i
++
)
{
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_KLV
,
NULL
,
ret
=
wl1271_cmd_template_set
(
wl
,
WL12XX_INVALID_ROLE_ID
,
CMD_TEMPL_KLV
,
NULL
,
sizeof
(
struct
ieee80211_qos_hdr
),
i
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
...
...
@@ -140,7 +154,8 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl,
IEEE80211_STYPE_DEAUTH
);
rate
=
wl1271_tx_min_rate_get
(
wl
,
wlvif
->
basic_rate_set
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_DEAUTH_AP
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_DEAUTH_AP
,
tmpl
,
sizeof
(
*
tmpl
),
0
,
rate
);
out:
...
...
@@ -172,7 +187,8 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl,
memcpy
(
nullfunc
->
addr3
,
vif
->
addr
,
ETH_ALEN
);
rate
=
wl1271_tx_min_rate_get
(
wl
,
wlvif
->
basic_rate_set
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_NULL_DATA
,
nullfunc
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_NULL_DATA
,
nullfunc
,
sizeof
(
*
nullfunc
),
0
,
rate
);
out:
...
...
@@ -204,7 +220,8 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl,
memcpy
(
qosnull
->
addr3
,
vif
->
addr
,
ETH_ALEN
);
rate
=
wl1271_tx_min_rate_get
(
wl
,
wlvif
->
basic_rate_set
);
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_QOS_NULL_DATA
,
qosnull
,
ret
=
wl1271_cmd_template_set
(
wl
,
wlvif
->
role_id
,
CMD_TEMPL_QOS_NULL_DATA
,
qosnull
,
sizeof
(
*
qosnull
),
0
,
rate
);
out:
...
...
drivers/net/wireless/wl12xx/io.c
View file @
8715d941
...
...
@@ -45,6 +45,65 @@
#define OCP_STATUS_REQ_FAILED 0x20000
#define OCP_STATUS_RESP_ERROR 0x30000
struct
wl1271_partition_set
wl12xx_part_table
[
PART_TABLE_LEN
]
=
{
[
PART_DOWN
]
=
{
.
mem
=
{
.
start
=
0x00000000
,
.
size
=
0x000177c0
},
.
reg
=
{
.
start
=
REGISTERS_BASE
,
.
size
=
0x00008800
},
.
mem2
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
.
mem3
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
},
[
PART_WORK
]
=
{
.
mem
=
{
.
start
=
0x00040000
,
.
size
=
0x00014fc0
},
.
reg
=
{
.
start
=
REGISTERS_BASE
,
.
size
=
0x0000a000
},
.
mem2
=
{
.
start
=
0x003004f8
,
.
size
=
0x00000004
},
.
mem3
=
{
.
start
=
0x00040404
,
.
size
=
0x00000000
},
},
[
PART_DRPW
]
=
{
.
mem
=
{
.
start
=
0x00040000
,
.
size
=
0x00014fc0
},
.
reg
=
{
.
start
=
DRPW_BASE
,
.
size
=
0x00006000
},
.
mem2
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
},
.
mem3
=
{
.
start
=
0x00000000
,
.
size
=
0x00000000
}
}
};
bool
wl1271_set_block_size
(
struct
wl1271
*
wl
)
{
if
(
wl
->
if_ops
->
set_block_size
)
{
...
...
drivers/net/wireless/wl12xx/io.h
View file @
8715d941
...
...
@@ -43,6 +43,8 @@
#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
extern
struct
wl1271_partition_set
wl12xx_part_table
[
PART_TABLE_LEN
];
struct
wl1271
;
void
wl1271_disable_interrupts
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/main.c
View file @
8715d941
This diff is collapsed.
Click to expand it.
drivers/net/wireless/wl12xx/ps.c
View file @
8715d941
...
...
@@ -56,7 +56,7 @@ void wl1271_elp_work(struct work_struct *work)
if
(
wlvif
->
bss_type
==
BSS_TYPE_AP_BSS
)
goto
out
;
if
(
!
test_bit
(
WLVIF_FLAG_
PSM
,
&
wlvif
->
flags
)
&&
if
(
!
test_bit
(
WLVIF_FLAG_
IN_PS
,
&
wlvif
->
flags
)
&&
test_bit
(
WLVIF_FLAG_IN_USE
,
&
wlvif
->
flags
))
goto
out
;
}
...
...
@@ -84,7 +84,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
if
(
wlvif
->
bss_type
==
BSS_TYPE_AP_BSS
)
return
;
if
(
!
test_bit
(
WLVIF_FLAG_
PSM
,
&
wlvif
->
flags
)
&&
if
(
!
test_bit
(
WLVIF_FLAG_
IN_PS
,
&
wlvif
->
flags
)
&&
test_bit
(
WLVIF_FLAG_IN_USE
,
&
wlvif
->
flags
))
return
;
}
...
...
@@ -160,28 +160,39 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
}
int
wl1271_ps_set_mode
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
enum
wl1271_cmd_ps_mode
mode
,
u32
rates
,
bool
send
)
enum
wl1271_cmd_ps_mode
mode
)
{
int
ret
;
u16
timeout
=
wl
->
conf
.
conn
.
dynamic_ps_timeout
;
switch
(
mode
)
{
case
STATION_AUTO_PS_MODE
:
case
STATION_POWER_SAVE_MODE
:
wl1271_debug
(
DEBUG_PSM
,
"entering psm"
);
wl1271_debug
(
DEBUG_PSM
,
"entering psm (mode=%d,timeout=%u)"
,
mode
,
timeout
);
ret
=
wl1271_acx_wake_up_conditions
(
wl
,
wlvif
);
ret
=
wl1271_acx_wake_up_conditions
(
wl
,
wlvif
,
wl
->
conf
.
conn
.
wake_up_event
,
wl
->
conf
.
conn
.
listen_interval
);
if
(
ret
<
0
)
{
wl1271_error
(
"couldn't set wake up conditions"
);
return
ret
;
}
ret
=
wl1271_cmd_ps_mode
(
wl
,
wlvif
,
STATION_POWER_SAVE_MODE
);
ret
=
wl1271_cmd_ps_mode
(
wl
,
wlvif
,
mode
,
timeout
);
if
(
ret
<
0
)
return
ret
;
set_bit
(
WLVIF_FLAG_PSM
,
&
wlvif
->
flags
);
set_bit
(
WLVIF_FLAG_IN_PS
,
&
wlvif
->
flags
);
/* enable beacon early termination. Not relevant for 5GHz */
if
(
wlvif
->
band
==
IEEE80211_BAND_2GHZ
)
{
ret
=
wl1271_acx_bet_enable
(
wl
,
wlvif
,
true
);
if
(
ret
<
0
)
return
ret
;
}
break
;
case
STATION_ACTIVE_MODE
:
default:
wl1271_debug
(
DEBUG_PSM
,
"leaving psm"
);
/* disable beacon early termination */
...
...
@@ -191,12 +202,15 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
return
ret
;
}
ret
=
wl1271_cmd_ps_mode
(
wl
,
wlvif
,
STATION_ACTIVE_MODE
);
ret
=
wl1271_cmd_ps_mode
(
wl
,
wlvif
,
mode
,
0
);
if
(
ret
<
0
)
return
ret
;
clear_bit
(
WLVIF_FLAG_
PSM
,
&
wlvif
->
flags
);
clear_bit
(
WLVIF_FLAG_
IN_PS
,
&
wlvif
->
flags
);
break
;
default:
wl1271_warning
(
"trying to set ps to unsupported mode %d"
,
mode
);
ret
=
-
EINVAL
;
}
return
ret
;
...
...
drivers/net/wireless/wl12xx/ps.h
View file @
8715d941
...
...
@@ -28,7 +28,7 @@
#include "acx.h"
int
wl1271_ps_set_mode
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
enum
wl1271_cmd_ps_mode
mode
,
u32
rates
,
bool
send
);
enum
wl1271_cmd_ps_mode
mode
);
void
wl1271_ps_elp_sleep
(
struct
wl1271
*
wl
);
int
wl1271_ps_elp_wakeup
(
struct
wl1271
*
wl
);
void
wl1271_elp_work
(
struct
work_struct
*
work
);
...
...
drivers/net/wireless/wl12xx/reg.h
View file @
8715d941
...
...
@@ -525,4 +525,31 @@ b12-b0 - Supported Rate indicator bits as defined below.
*/
#define INTR_TRIG_TX_PROC1 BIT(18)
#define WL127X_REG_FUSE_DATA_2_1 0x050a
#define WL128X_REG_FUSE_DATA_2_1 0x2152
#define PG_VER_MASK 0x3c
#define PG_VER_OFFSET 2
#define WL127X_PG_MAJOR_VER_MASK 0x3
#define WL127X_PG_MAJOR_VER_OFFSET 0x0
#define WL127X_PG_MINOR_VER_MASK 0xc
#define WL127X_PG_MINOR_VER_OFFSET 0x2
#define WL128X_PG_MAJOR_VER_MASK 0xc
#define WL128X_PG_MAJOR_VER_OFFSET 0x2
#define WL128X_PG_MINOR_VER_MASK 0x3
#define WL128X_PG_MINOR_VER_OFFSET 0x0
#define WL127X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL127X_PG_MAJOR_VER_MASK) >> \
WL127X_PG_MAJOR_VER_OFFSET)
#define WL127X_PG_GET_MINOR(pg_ver) ((pg_ver & WL127X_PG_MINOR_VER_MASK) >> \
WL127X_PG_MINOR_VER_OFFSET)
#define WL128X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL128X_PG_MAJOR_VER_MASK) >> \
WL128X_PG_MAJOR_VER_OFFSET)
#define WL128X_PG_GET_MINOR(pg_ver) ((pg_ver & WL128X_PG_MINOR_VER_MASK) >> \
WL128X_PG_MINOR_VER_OFFSET)
#define WL12XX_REG_FUSE_BD_ADDR_1 0x00310eb4
#define WL12XX_REG_FUSE_BD_ADDR_2 0x00310eb8
#endif
drivers/net/wireless/wl12xx/rx.c
View file @
8715d941
...
...
@@ -113,7 +113,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
* In PLT mode we seem to get frames and mac80211 warns about them,
* workaround this by not retrieving them at all.
*/
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_PLT
))
if
(
unlikely
(
wl
->
plt
))
return
-
EINVAL
;
/* the data read starts with the descriptor */
...
...
drivers/net/wireless/wl12xx/scan.c
View file @
8715d941
...
...
@@ -38,7 +38,6 @@ void wl1271_scan_complete_work(struct work_struct *work)
struct
ieee80211_vif
*
vif
;
struct
wl12xx_vif
*
wlvif
;
int
ret
;
bool
is_sta
,
is_ibss
;
dwork
=
container_of
(
work
,
struct
delayed_work
,
work
);
wl
=
container_of
(
dwork
,
struct
wl1271
,
scan_complete_work
);
...
...
@@ -70,15 +69,6 @@ void wl1271_scan_complete_work(struct work_struct *work)
wl1271_cmd_build_ap_probe_req
(
wl
,
wlvif
,
wlvif
->
probereq
);
}
/* return to ROC if needed */
is_sta
=
(
wlvif
->
bss_type
==
BSS_TYPE_STA_BSS
);
is_ibss
=
(
wlvif
->
bss_type
==
BSS_TYPE_IBSS
);
if
(((
is_sta
&&
!
test_bit
(
WLVIF_FLAG_STA_ASSOCIATED
,
&
wlvif
->
flags
))
||
(
is_ibss
&&
!
test_bit
(
WLVIF_FLAG_IBSS_JOINED
,
&
wlvif
->
flags
)))
&&
!
test_bit
(
wlvif
->
dev_role_id
,
wl
->
roc_map
))
{
/* restore remain on channel */
wl12xx_start_dev
(
wl
,
wlvif
);
}
wl1271_ps_elp_sleep
(
wl
);
if
(
wl
->
scan
.
failed
)
{
...
...
@@ -182,14 +172,23 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
goto
out
;
}
if
(
wl
->
conf
.
scan
.
split_scan_timeout
)
scan_options
|=
WL1271_SCAN_OPT_SPLIT_SCAN
;
if
(
passive
)
scan_options
|=
WL1271_SCAN_OPT_PASSIVE
;
if
(
WARN_ON
(
wlvif
->
role_id
==
WL12XX_INVALID_ROLE_ID
))
{
if
(
wlvif
->
bss_type
==
BSS_TYPE_AP_BSS
||
test_bit
(
WLVIF_FLAG_STA_ASSOCIATED
,
&
wlvif
->
flags
))
cmd
->
params
.
role_id
=
wlvif
->
role_id
;
else
cmd
->
params
.
role_id
=
wlvif
->
dev_role_id
;
if
(
WARN_ON
(
cmd
->
params
.
role_id
==
WL12XX_INVALID_ROLE_ID
))
{
ret
=
-
EINVAL
;
goto
out
;
}
cmd
->
params
.
role_id
=
wlvif
->
role_id
;
cmd
->
params
.
scan_options
=
cpu_to_le16
(
scan_options
);
cmd
->
params
.
n_ch
=
wl1271_get_scan_channels
(
wl
,
wl
->
scan
.
req
,
...
...
@@ -202,7 +201,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
cmd
->
params
.
tx_rate
=
cpu_to_le32
(
basic_rate
);
cmd
->
params
.
n_probe_reqs
=
wl
->
conf
.
scan
.
num_probe_reqs
;
cmd
->
params
.
tid_trigger
=
0
;
cmd
->
params
.
tid_trigger
=
CONF_TX_AC_ANY_TID
;
cmd
->
params
.
scan_tag
=
WL1271_SCAN_DEFAULT_TAG
;
if
(
band
==
IEEE80211_BAND_2GHZ
)
...
...
@@ -217,16 +216,17 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif,
memcpy
(
cmd
->
addr
,
vif
->
addr
,
ETH_ALEN
);
ret
=
wl1271_cmd_build_probe_req
(
wl
,
wlvif
,
wl
->
scan
.
ssid
,
wl
->
scan
.
ssid_len
,
wl
->
scan
.
req
->
ie
,
wl
->
scan
.
req
->
ie_len
,
band
);
ret
=
wl12xx_cmd_build_probe_req
(
wl
,
wlvif
,
cmd
->
params
.
role_id
,
band
,
wl
->
scan
.
ssid
,
wl
->
scan
.
ssid_len
,
wl
->
scan
.
req
->
ie
,
wl
->
scan
.
req
->
ie_len
);
if
(
ret
<
0
)
{
wl1271_error
(
"PROBE request template failed"
);
goto
out
;
}
/* disable the timeout */
trigger
->
timeout
=
0
;
trigger
->
timeout
=
cpu_to_le32
(
wl
->
conf
.
scan
.
split_scan_timeout
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_TRIGGER_SCAN_TO
,
trigger
,
sizeof
(
*
trigger
),
0
);
if
(
ret
<
0
)
{
...
...
@@ -658,11 +658,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
}
if
(
!
force_passive
&&
cfg
->
active
[
0
])
{
ret
=
wl1271_cmd_build_probe_req
(
wl
,
wlvif
,
req
->
ssids
[
0
].
ssid
,
u8
band
=
IEEE80211_BAND_2GHZ
;
ret
=
wl12xx_cmd_build_probe_req
(
wl
,
wlvif
,
wlvif
->
dev_role_id
,
band
,
req
->
ssids
[
0
].
ssid
,
req
->
ssids
[
0
].
ssid_len
,
ies
->
ie
[
IEEE80211_BAND_2GHZ
],
ies
->
len
[
IEEE80211_BAND_2GHZ
],
IEEE80211_BAND_2GHZ
);
ies
->
ie
[
band
],
ies
->
len
[
band
]);
if
(
ret
<
0
)
{
wl1271_error
(
"2.4GHz PROBE request template failed"
);
goto
out
;
...
...
@@ -670,11 +672,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
}
if
(
!
force_passive
&&
cfg
->
active
[
1
])
{
ret
=
wl1271_cmd_build_probe_req
(
wl
,
wlvif
,
req
->
ssids
[
0
].
ssid
,
u8
band
=
IEEE80211_BAND_5GHZ
;
ret
=
wl12xx_cmd_build_probe_req
(
wl
,
wlvif
,
wlvif
->
dev_role_id
,
band
,
req
->
ssids
[
0
].
ssid
,
req
->
ssids
[
0
].
ssid_len
,
ies
->
ie
[
IEEE80211_BAND_5GHZ
],
ies
->
len
[
IEEE80211_BAND_5GHZ
],
IEEE80211_BAND_5GHZ
);
ies
->
ie
[
band
],
ies
->
len
[
band
]);
if
(
ret
<
0
)
{
wl1271_error
(
"5GHz PROBE request template failed"
);
goto
out
;
...
...
drivers/net/wireless/wl12xx/scan.h
View file @
8715d941
...
...
@@ -48,7 +48,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl);
#define WL1271_SCAN_CURRENT_TX_PWR 0
#define WL1271_SCAN_OPT_ACTIVE 0
#define WL1271_SCAN_OPT_PASSIVE 1
#define WL1271_SCAN_OPT_
TRIGGERED_SCAN
2
#define WL1271_SCAN_OPT_
SPLIT_SCAN
2
#define WL1271_SCAN_OPT_PRIORITY_HIGH 4
/* scan even if we fail to enter psm */
#define WL1271_SCAN_OPT_FORCE 8
...
...
drivers/net/wireless/wl12xx/sdio.c
View file @
8715d941
...
...
@@ -74,6 +74,8 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
struct
wl12xx_sdio_glue
*
glue
=
dev_get_drvdata
(
child
->
parent
);
struct
sdio_func
*
func
=
dev_to_sdio_func
(
glue
->
dev
);
sdio_claim_host
(
func
);
if
(
unlikely
(
addr
==
HW_ACCESS_ELP_CTRL_REG_ADDR
))
{
((
u8
*
)
buf
)[
0
]
=
sdio_f0_readb
(
func
,
addr
,
&
ret
);
dev_dbg
(
child
->
parent
,
"sdio read 52 addr 0x%x, byte 0x%02x
\n
"
,
...
...
@@ -88,6 +90,8 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
addr
,
len
);
}
sdio_release_host
(
func
);
if
(
ret
)
dev_err
(
child
->
parent
,
"sdio read failed (%d)
\n
"
,
ret
);
}
...
...
@@ -99,6 +103,8 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
struct
wl12xx_sdio_glue
*
glue
=
dev_get_drvdata
(
child
->
parent
);
struct
sdio_func
*
func
=
dev_to_sdio_func
(
glue
->
dev
);
sdio_claim_host
(
func
);
if
(
unlikely
(
addr
==
HW_ACCESS_ELP_CTRL_REG_ADDR
))
{
sdio_f0_writeb
(
func
,
((
u8
*
)
buf
)[
0
],
addr
,
&
ret
);
dev_dbg
(
child
->
parent
,
"sdio write 52 addr 0x%x, byte 0x%02x
\n
"
,
...
...
@@ -113,6 +119,8 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
ret
=
sdio_memcpy_toio
(
func
,
addr
,
buf
,
len
);
}
sdio_release_host
(
func
);
if
(
ret
)
dev_err
(
child
->
parent
,
"sdio write failed (%d)
\n
"
,
ret
);
}
...
...
@@ -136,6 +144,7 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
sdio_claim_host
(
func
);
sdio_enable_func
(
func
);
sdio_release_host
(
func
);
out:
return
ret
;
...
...
@@ -146,6 +155,7 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
int
ret
;
struct
sdio_func
*
func
=
dev_to_sdio_func
(
glue
->
dev
);
sdio_claim_host
(
func
);
sdio_disable_func
(
func
);
sdio_release_host
(
func
);
...
...
@@ -314,9 +324,6 @@ static int wl1271_suspend(struct device *dev)
dev_err
(
dev
,
"error while trying to keep power
\n
"
);
goto
out
;
}
/* release host */
sdio_release_host
(
func
);
}
out:
return
ret
;
...
...
@@ -324,15 +331,7 @@ static int wl1271_suspend(struct device *dev)
static
int
wl1271_resume
(
struct
device
*
dev
)
{
struct
sdio_func
*
func
=
dev_to_sdio_func
(
dev
);
struct
wl12xx_sdio_glue
*
glue
=
sdio_get_drvdata
(
func
);
struct
wl1271
*
wl
=
platform_get_drvdata
(
glue
->
core
);
dev_dbg
(
dev
,
"wl1271 resume
\n
"
);
if
(
wl
->
wow_enabled
)
{
/* claim back host */
sdio_claim_host
(
func
);
}
return
0
;
}
...
...
@@ -371,5 +370,9 @@ module_exit(wl1271_exit);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL127X_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_FW_NAME_SINGLE
);
MODULE_FIRMWARE
(
WL127X_FW_NAME_MULTI
);
MODULE_FIRMWARE
(
WL127X_PLT_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME_SINGLE
);
MODULE_FIRMWARE
(
WL128X_FW_NAME_MULTI
);
MODULE_FIRMWARE
(
WL128X_PLT_FW_NAME
);
drivers/net/wireless/wl12xx/spi.c
View file @
8715d941
...
...
@@ -433,6 +433,10 @@ module_exit(wl1271_exit);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL127X_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_FW_NAME_SINGLE
);
MODULE_FIRMWARE
(
WL127X_FW_NAME_MULTI
);
MODULE_FIRMWARE
(
WL127X_PLT_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME_SINGLE
);
MODULE_FIRMWARE
(
WL128X_FW_NAME_MULTI
);
MODULE_FIRMWARE
(
WL128X_PLT_FW_NAME
);
MODULE_ALIAS
(
"spi:wl1271"
);
drivers/net/wireless/wl12xx/testmode.c
View file @
8715d941
...
...
@@ -30,6 +30,7 @@
#include "acx.h"
#include "reg.h"
#include "ps.h"
#include "io.h"
#define WL1271_TM_MAX_DATA_LENGTH 1024
...
...
@@ -41,6 +42,7 @@ enum wl1271_tm_commands {
WL1271_TM_CMD_NVS_PUSH
,
/* Not in use. Keep to not break ABI */
WL1271_TM_CMD_SET_PLT_MODE
,
WL1271_TM_CMD_RECOVER
,
WL1271_TM_CMD_GET_MAC
,
__WL1271_TM_CMD_AFTER_LAST
};
...
...
@@ -264,6 +266,52 @@ static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[])
return
0
;
}
static
int
wl12xx_tm_cmd_get_mac
(
struct
wl1271
*
wl
,
struct
nlattr
*
tb
[])
{
struct
sk_buff
*
skb
;
u8
mac_addr
[
ETH_ALEN
];
int
ret
=
0
;
mutex_lock
(
&
wl
->
mutex
);
if
(
!
wl
->
plt
)
{
ret
=
-
EINVAL
;
goto
out
;
}
if
(
wl
->
fuse_oui_addr
==
0
&&
wl
->
fuse_nic_addr
==
0
)
{
ret
=
-
EOPNOTSUPP
;
goto
out
;
}
mac_addr
[
0
]
=
(
u8
)(
wl
->
fuse_oui_addr
>>
16
);
mac_addr
[
1
]
=
(
u8
)(
wl
->
fuse_oui_addr
>>
8
);
mac_addr
[
2
]
=
(
u8
)
wl
->
fuse_oui_addr
;
mac_addr
[
3
]
=
(
u8
)(
wl
->
fuse_nic_addr
>>
16
);
mac_addr
[
4
]
=
(
u8
)(
wl
->
fuse_nic_addr
>>
8
);
mac_addr
[
5
]
=
(
u8
)
wl
->
fuse_nic_addr
;
skb
=
cfg80211_testmode_alloc_reply_skb
(
wl
->
hw
->
wiphy
,
ETH_ALEN
);
if
(
!
skb
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
NLA_PUT
(
skb
,
WL1271_TM_ATTR_DATA
,
ETH_ALEN
,
mac_addr
);
ret
=
cfg80211_testmode_reply
(
skb
);
if
(
ret
<
0
)
goto
out
;
out:
mutex_unlock
(
&
wl
->
mutex
);
return
ret
;
nla_put_failure:
kfree_skb
(
skb
);
ret
=
-
EMSGSIZE
;
goto
out
;
}
int
wl1271_tm_cmd
(
struct
ieee80211_hw
*
hw
,
void
*
data
,
int
len
)
{
struct
wl1271
*
wl
=
hw
->
priv
;
...
...
@@ -288,6 +336,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
return
wl1271_tm_cmd_set_plt_mode
(
wl
,
tb
);
case
WL1271_TM_CMD_RECOVER
:
return
wl1271_tm_cmd_recover
(
wl
,
tb
);
case
WL1271_TM_CMD_GET_MAC
:
return
wl12xx_tm_cmd_get_mac
(
wl
,
tb
);
default:
return
-
EOPNOTSUPP
;
}
...
...
drivers/net/wireless/wl12xx/tx.c
View file @
8715d941
...
...
@@ -77,35 +77,6 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id)
}
}
static
int
wl1271_tx_update_filters
(
struct
wl1271
*
wl
,
struct
wl12xx_vif
*
wlvif
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_hdr
*
hdr
;
int
ret
;
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
/*
* stop bssid-based filtering before transmitting authentication
* requests. this way the hw will never drop authentication
* responses coming from BSSIDs it isn't familiar with (e.g. on
* roaming)
*/
if
(
!
ieee80211_is_auth
(
hdr
->
frame_control
))
return
0
;
if
(
wlvif
->
dev_hlid
!=
WL12XX_INVALID_LINK_ID
)
goto
out
;
wl1271_debug
(
DEBUG_CMD
,
"starting device role for roaming"
);
ret
=
wl12xx_start_dev
(
wl
,
wlvif
);
if
(
ret
<
0
)
goto
out
;
out:
return
0
;
}
static
void
wl1271_tx_ap_update_inconnection_sta
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
...
...
@@ -187,8 +158,6 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if
(
wlvif
->
bss_type
==
BSS_TYPE_AP_BSS
)
return
wl12xx_tx_get_hlid_ap
(
wl
,
wlvif
,
skb
);
wl1271_tx_update_filters
(
wl
,
wlvif
,
skb
);
if
((
test_bit
(
WLVIF_FLAG_STA_ASSOCIATED
,
&
wlvif
->
flags
)
||
test_bit
(
WLVIF_FLAG_IBSS_JOINED
,
&
wlvif
->
flags
))
&&
!
ieee80211_is_auth
(
hdr
->
frame_control
)
&&
...
...
@@ -286,16 +255,20 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
int
aligned_len
,
ac
,
rate_idx
;
s64
hosttime
;
u16
tx_attr
=
0
;
__le16
frame_control
;
struct
ieee80211_hdr
*
hdr
;
u8
*
frame_start
;
bool
is_dummy
;
desc
=
(
struct
wl1271_tx_hw_descr
*
)
skb
->
data
;
frame_start
=
(
u8
*
)(
desc
+
1
);
hdr
=
(
struct
ieee80211_hdr
*
)(
frame_start
+
extra
);
frame_control
=
hdr
->
frame_control
;
/* relocate space for security header */
if
(
extra
)
{
void
*
framestart
=
skb
->
data
+
sizeof
(
*
desc
);
u16
fc
=
*
(
u16
*
)(
framestart
+
extra
);
int
hdrlen
=
ieee80211_hdrlen
(
cpu_to_le16
(
fc
));
memmove
(
framestart
,
framestart
+
extra
,
hdrlen
);
int
hdrlen
=
ieee80211_hdrlen
(
frame_control
);
memmove
(
frame_start
,
hdr
,
hdrlen
);
}
/* configure packet life time */
...
...
@@ -384,6 +357,11 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
desc
->
wl127x_mem
.
total_mem_blocks
);
}
/* for WEP shared auth - no fw encryption is needed */
if
(
ieee80211_is_auth
(
frame_control
)
&&
ieee80211_has_protected
(
frame_control
))
tx_attr
|=
TX_HW_ATTR_HOST_ENCRYPT
;
desc
->
tx_attr
=
cpu_to_le16
(
tx_attr
);
}
...
...
@@ -408,7 +386,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if
(
info
->
control
.
hw_key
&&
info
->
control
.
hw_key
->
cipher
==
WLAN_CIPHER_SUITE_TKIP
)
extra
=
WL1271_
TKIP_IV_SPACE
;
extra
=
WL1271_
EXTRA_SPACE_TKIP
;
if
(
info
->
control
.
hw_key
)
{
bool
is_wep
;
...
...
@@ -795,6 +773,18 @@ void wl1271_tx_work(struct work_struct *work)
mutex_unlock
(
&
wl
->
mutex
);
}
static
u8
wl1271_tx_get_rate_flags
(
u8
rate_class_index
)
{
u8
flags
=
0
;
if
(
rate_class_index
>=
CONF_HW_RXTX_RATE_MCS_MIN
&&
rate_class_index
<=
CONF_HW_RXTX_RATE_MCS_MAX
)
flags
|=
IEEE80211_TX_RC_MCS
;
if
(
rate_class_index
==
CONF_HW_RXTX_RATE_MCS7_SGI
)
flags
|=
IEEE80211_TX_RC_SHORT_GI
;
return
flags
;
}
static
void
wl1271_tx_complete_packet
(
struct
wl1271
*
wl
,
struct
wl1271_tx_hw_res_descr
*
result
)
{
...
...
@@ -804,6 +794,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
struct
sk_buff
*
skb
;
int
id
=
result
->
id
;
int
rate
=
-
1
;
u8
rate_flags
=
0
;
u8
retries
=
0
;
/* check for id legality */
...
...
@@ -830,6 +821,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
info
->
flags
|=
IEEE80211_TX_STAT_ACK
;
rate
=
wl1271_rate_to_idx
(
result
->
rate_class_index
,
wlvif
->
band
);
rate_flags
=
wl1271_tx_get_rate_flags
(
result
->
rate_class_index
);
retries
=
result
->
ack_failures
;
}
else
if
(
result
->
status
==
TX_RETRY_EXCEEDED
)
{
wl
->
stats
.
excessive_retries
++
;
...
...
@@ -838,7 +830,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
info
->
status
.
rates
[
0
].
idx
=
rate
;
info
->
status
.
rates
[
0
].
count
=
retries
;
info
->
status
.
rates
[
0
].
flags
=
0
;
info
->
status
.
rates
[
0
].
flags
=
rate_flags
;
info
->
status
.
ack_signal
=
-
1
;
wl
->
stats
.
retry_count
+=
result
->
ack_failures
;
...
...
@@ -869,8 +861,9 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
if
(
info
->
control
.
hw_key
&&
info
->
control
.
hw_key
->
cipher
==
WLAN_CIPHER_SUITE_TKIP
)
{
int
hdrlen
=
ieee80211_get_hdrlen_from_skb
(
skb
);
memmove
(
skb
->
data
+
WL1271_TKIP_IV_SPACE
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
WL1271_TKIP_IV_SPACE
);
memmove
(
skb
->
data
+
WL1271_EXTRA_SPACE_TKIP
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
WL1271_EXTRA_SPACE_TKIP
);
}
wl1271_debug
(
DEBUG_TX
,
"tx status id %u skb 0x%p failures %u rate 0x%x"
...
...
@@ -1012,9 +1005,9 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
info
->
control
.
hw_key
->
cipher
==
WLAN_CIPHER_SUITE_TKIP
)
{
int
hdrlen
=
ieee80211_get_hdrlen_from_skb
(
skb
);
memmove
(
skb
->
data
+
WL1271_
TKIP_IV_SPACE
,
memmove
(
skb
->
data
+
WL1271_
EXTRA_SPACE_TKIP
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
WL1271_
TKIP_IV_SPACE
);
skb_pull
(
skb
,
WL1271_
EXTRA_SPACE_TKIP
);
}
info
->
status
.
rates
[
0
].
idx
=
-
1
;
...
...
drivers/net/wireless/wl12xx/tx.h
View file @
8715d941
...
...
@@ -39,6 +39,7 @@
#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_HOST_ENCRYPT BIT(14)
#define TX_HW_ATTR_OFST_SAVE_RETRIES 0
#define TX_HW_ATTR_OFST_HEADER_PAD 1
...
...
@@ -51,7 +52,9 @@
#define TX_HW_RESULT_QUEUE_LEN_MASK 0xf
#define WL1271_TX_ALIGN_TO 4
#define WL1271_TKIP_IV_SPACE 4
#define WL1271_EXTRA_SPACE_TKIP 4
#define WL1271_EXTRA_SPACE_AES 8
#define WL1271_EXTRA_SPACE_MAX 8
/* Used for management frames and dummy packets */
#define WL1271_TID_MGMT 7
...
...
drivers/net/wireless/wl12xx/wl12xx.h
View file @
8715d941
...
...
@@ -35,8 +35,14 @@
#include "conf.h"
#include "ini.h"
#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin"
#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin"
#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
/*
* wl127x and wl128x are using the same NVS file name. However, the
...
...
@@ -90,7 +96,13 @@
enum
wl1271_state
{
WL1271_STATE_OFF
,
WL1271_STATE_ON
,
WL1271_STATE_PLT
,
};
enum
wl12xx_fw_type
{
WL12XX_FW_TYPE_NONE
,
WL12XX_FW_TYPE_NORMAL
,
WL12XX_FW_TYPE_MULTI
,
WL12XX_FW_TYPE_PLT
,
};
enum
wl1271_partition_type
{
...
...
@@ -247,6 +259,7 @@ enum wl12xx_flags {
WL1271_FLAG_PENDING_WORK
,
WL1271_FLAG_SOFT_GEMINI
,
WL1271_FLAG_RECOVERY_IN_PROGRESS
,
WL1271_FLAG_VIF_CHANGE_IN_PROGRESS
,
};
enum
wl12xx_vif_flags
{
...
...
@@ -254,8 +267,7 @@ enum wl12xx_vif_flags {
WLVIF_FLAG_STA_ASSOCIATED
,
WLVIF_FLAG_IBSS_JOINED
,
WLVIF_FLAG_AP_STARTED
,
WLVIF_FLAG_PSM
,
WLVIF_FLAG_PSM_REQUESTED
,
WLVIF_FLAG_IN_PS
,
WLVIF_FLAG_STA_STATE_SENT
,
WLVIF_FLAG_RX_STREAMING_STARTED
,
WLVIF_FLAG_PSPOLL_FAILURE
,
...
...
@@ -295,6 +307,9 @@ struct wl1271 {
spinlock_t
wl_lock
;
enum
wl1271_state
state
;
enum
wl12xx_fw_type
fw_type
;
bool
plt
;
u8
last_vif_count
;
struct
mutex
mutex
;
unsigned
long
flags
;
...
...
@@ -313,7 +328,12 @@ struct wl1271 {
s8
hw_pg_ver
;
u8
mac_addr
[
ETH_ALEN
];
/* address read from the fuse ROM */
u32
fuse_oui_addr
;
u32
fuse_nic_addr
;
/* we have up to 2 MAC addresses */
struct
mac_address
addresses
[
2
];
int
channel
;
u8
system_hlid
;
...
...
@@ -425,8 +445,6 @@ struct wl1271 {
struct
wl12xx_fw_status
*
fw_status
;
struct
wl1271_tx_hw_res_if
*
tx_res_if
;
struct
ieee80211_vif
*
vif
;
/* Current chipset configuration */
struct
conf_drv_settings
conf
;
...
...
@@ -503,6 +521,8 @@ struct wl12xx_vif {
u8
basic_rate_idx
;
u8
ap_rate_idx
;
u8
p2p_rate_idx
;
bool
qos
;
}
sta
;
struct
{
u8
global_hlid
;
...
...
@@ -560,12 +580,6 @@ struct wl12xx_vif {
/* Session counter for the chipset */
int
session_counter
;
struct
completion
*
ps_compl
;
struct
delayed_work
pspoll_work
;
/* counter for ps-poll delivery failures */
int
ps_poll_failures
;
/* retry counter for PSM entries */
u8
psm_entry_retry
;
...
...
@@ -575,6 +589,10 @@ struct wl12xx_vif {
int
rssi_thold
;
int
last_rssi_event
;
/* save the current encryption type for auto-arp config */
u8
encryption_type
;
__be32
ip_addr
;
/* RX BA constraint value */
bool
ba_support
;
bool
ba_allowed
;
...
...
drivers/net/wireless/wl12xx/wl12xx_80211.h
View file @
8715d941
...
...
@@ -117,7 +117,7 @@ struct wl12xx_ps_poll_template {
}
__packed
;
struct
wl12xx_arp_rsp_template
{
struct
ieee80211_hdr_3addr
hdr
;
/* not including ieee80211 header */
u8
llc_hdr
[
sizeof
(
rfc1042_header
)];
__be16
llc_type
;
...
...
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