Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
8715d941
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
8715d941
编写于
2月 22, 2012
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
上级
ca994a36
51c4ed95
变更
33
展开全部
隐藏空白更改
内联
并排
Showing
33 changed file
with
1386 addition
and
798 deletion
+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
未找到文件。
drivers/net/wireless/wl1251/Makefile
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
8715d941
此差异已折叠。
点击以展开。
drivers/net/wireless/wl12xx/ps.c
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录