Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
890641b2
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 大约 4 年
通知
14
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
890641b2
编写于
5月 05, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
上级
eaef6a93
25eaea30
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
852 addition
and
280 deletion
+852
-280
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+142
-48
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+87
-16
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+2
-4
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+14
-4
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+62
-28
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+239
-0
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+0
-47
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/event.h
+1
-11
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+81
-29
drivers/net/wireless/wl12xx/init.h
drivers/net/wireless/wl12xx/init.h
+2
-0
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+158
-74
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+24
-6
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+28
-8
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+9
-4
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+1
-1
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+2
-0
未找到文件。
drivers/net/wireless/wl12xx/acx.c
浏览文件 @
890641b2
...
...
@@ -325,12 +325,19 @@ int wl1271_acx_service_period_timeout(struct wl1271 *wl)
return
ret
;
}
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
16
rts_threshold
)
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
32
rts_threshold
)
{
struct
acx_rts_threshold
*
rts
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx rts threshold"
);
/*
* If the RTS threshold is not configured or out of range, use the
* default value.
*/
if
(
rts_threshold
>
IEEE80211_MAX_RTS_THRESHOLD
)
rts_threshold
=
wl
->
conf
.
rx
.
rts_threshold
;
wl1271_debug
(
DEBUG_ACX
,
"acx rts threshold: %d"
,
rts_threshold
);
rts
=
kzalloc
(
sizeof
(
*
rts
),
GFP_KERNEL
);
if
(
!
rts
)
{
...
...
@@ -338,7 +345,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
goto
out
;
}
rts
->
threshold
=
cpu_to_le16
(
rts_threshold
);
rts
->
threshold
=
cpu_to_le16
(
(
u16
)
rts_threshold
);
ret
=
wl1271_cmd_configure
(
wl
,
DOT11_RTS_THRESHOLD
,
rts
,
sizeof
(
*
rts
));
if
(
ret
<
0
)
{
...
...
@@ -540,13 +547,13 @@ int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
return
ret
;
}
int
wl1271_acx_sg_cfg
(
struct
wl1271
*
wl
)
int
wl1271_acx_s
ta_s
g_cfg
(
struct
wl1271
*
wl
)
{
struct
acx_bt_wlan_coex_param
*
param
;
struct
acx_
sta_
bt_wlan_coex_param
*
param
;
struct
conf_sg_settings
*
c
=
&
wl
->
conf
.
sg
;
int
i
,
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sg cfg"
);
wl1271_debug
(
DEBUG_ACX
,
"acx sg
sta
cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
...
...
@@ -555,8 +562,38 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
}
/* BT-WLAN coext parameters */
for
(
i
=
0
;
i
<
CONF_SG_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
params
[
i
]);
for
(
i
=
0
;
i
<
CONF_SG_STA_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
sta_params
[
i
]);
param
->
param_idx
=
CONF_SG_PARAMS_ALL
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SG_CFG
,
param
,
sizeof
(
*
param
));
if
(
ret
<
0
)
{
wl1271_warning
(
"failed to set sg config: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
param
);
return
ret
;
}
int
wl1271_acx_ap_sg_cfg
(
struct
wl1271
*
wl
)
{
struct
acx_ap_bt_wlan_coex_param
*
param
;
struct
conf_sg_settings
*
c
=
&
wl
->
conf
.
sg
;
int
i
,
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sg ap cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
/* BT-WLAN coext parameters */
for
(
i
=
0
;
i
<
CONF_SG_AP_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
ap_params
[
i
]);
param
->
param_idx
=
CONF_SG_PARAMS_ALL
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SG_CFG
,
param
,
sizeof
(
*
param
));
...
...
@@ -804,7 +841,8 @@ int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
struct
acx_ap_rate_policy
*
acx
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx ap rate policy"
);
wl1271_debug
(
DEBUG_ACX
,
"acx ap rate policy %d rates 0x%x"
,
idx
,
c
->
enabled_rates
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
...
...
@@ -898,12 +936,19 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
return
ret
;
}
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
16
frag_threshold
)
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
32
frag_threshold
)
{
struct
acx_frag_threshold
*
acx
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx frag threshold"
);
/*
* If the fragmentation is not configured or out of range, use the
* default value.
*/
if
(
frag_threshold
>
IEEE80211_MAX_FRAG_THRESHOLD
)
frag_threshold
=
wl
->
conf
.
tx
.
frag_threshold
;
wl1271_debug
(
DEBUG_ACX
,
"acx frag threshold: %d"
,
frag_threshold
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
...
...
@@ -912,7 +957,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
goto
out
;
}
acx
->
frag_threshold
=
cpu_to_le16
(
frag_threshold
);
acx
->
frag_threshold
=
cpu_to_le16
(
(
u16
)
frag_threshold
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_FRAG_CFG
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"Setting of frag threshold failed: %d"
,
ret
);
...
...
@@ -954,6 +999,7 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl)
int
wl1271_acx_ap_mem_cfg
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_ap_config_memory
*
mem_conf
;
struct
conf_memory_settings
*
mem
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"wl1271 mem cfg"
);
...
...
@@ -964,14 +1010,21 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
goto
out
;
}
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
/*
* FIXME: The 128x AP FW does not yet support dynamic memory.
* Use the base memory configuration for 128x for now. This
* should be fine tuned in the future.
*/
mem
=
&
wl
->
conf
.
mem_wl128x
;
else
mem
=
&
wl
->
conf
.
mem_wl127x
;
/* memory config */
/* FIXME: for now we always use mem_wl127x for AP, because it
* doesn't support dynamic memory and we don't have the
* optimal values for wl128x without dynamic memory yet */
mem_conf
->
num_stations
=
wl
->
conf
.
mem_wl127x
.
num_stations
;
mem_conf
->
rx_mem_block_num
=
wl
->
conf
.
mem_wl127x
.
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
wl
->
conf
.
mem_wl127x
.
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
wl
->
conf
.
mem_wl127x
.
ssid_profiles
;
mem_conf
->
num_stations
=
mem
->
num_stations
;
mem_conf
->
rx_mem_block_num
=
mem
->
rx_block_num
;
mem_conf
->
tx_min_mem_block_num
=
mem
->
tx_min_block_num
;
mem_conf
->
num_ssid_profiles
=
mem
->
ssid_profiles
;
mem_conf
->
total_tx_descriptors
=
cpu_to_le32
(
ACX_TX_DESCRIPTORS
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MEM_CFG
,
mem_conf
,
...
...
@@ -1524,46 +1577,22 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
return
ret
;
}
int
wl1271_acx_
ap_
max_tx_retry
(
struct
wl1271
*
wl
)
int
wl1271_acx_max_tx_retry
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_
ap_
max_tx_retry
*
acx
=
NULL
;
struct
wl1271_acx_max_tx_retry
*
acx
=
NULL
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx
ap
max tx retry"
);
wl1271_debug
(
DEBUG_ACX
,
"acx max tx retry"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
max_tx_retry
=
cpu_to_le16
(
wl
->
conf
.
tx
.
max_tx_retries
);
acx
->
max_tx_retry
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_
max_tx_retries
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MAX_TX_FAILURE
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx ap max tx retry failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
int
wl1271_acx_sta_max_tx_retry
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_sta_max_tx_retry
*
acx
=
NULL
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sta max tx retry"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
max_tx_retry
=
wl
->
conf
.
tx
.
max_tx_retries
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_CONS_TX_FAILURE
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx sta max tx retry failed: %d"
,
ret
);
wl1271_warning
(
"acx max tx retry failed: %d"
,
ret
);
goto
out
;
}
...
...
@@ -1626,3 +1655,68 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
kfree
(
acx
);
return
ret
;
}
int
wl1271_acx_set_ap_beacon_filter
(
struct
wl1271
*
wl
,
bool
enable
)
{
struct
acx_ap_beacon_filter
*
acx
=
NULL
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx set ap beacon filter: %d"
,
enable
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
enable
=
enable
?
1
:
0
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_AP_BEACON_FILTER_OPT
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx set ap beacon filter failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
int
wl1271_acx_fm_coex
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_fm_coex
*
acx
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx fm coex setting"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
acx
->
enable
=
wl
->
conf
.
fm_coex
.
enable
;
acx
->
swallow_period
=
wl
->
conf
.
fm_coex
.
swallow_period
;
acx
->
n_divider_fref_set_1
=
wl
->
conf
.
fm_coex
.
n_divider_fref_set_1
;
acx
->
n_divider_fref_set_2
=
wl
->
conf
.
fm_coex
.
n_divider_fref_set_2
;
acx
->
m_divider_fref_set_1
=
cpu_to_le16
(
wl
->
conf
.
fm_coex
.
m_divider_fref_set_1
);
acx
->
m_divider_fref_set_2
=
cpu_to_le16
(
wl
->
conf
.
fm_coex
.
m_divider_fref_set_2
);
acx
->
coex_pll_stabilization_time
=
cpu_to_le32
(
wl
->
conf
.
fm_coex
.
coex_pll_stabilization_time
);
acx
->
ldo_stabilization_time
=
cpu_to_le16
(
wl
->
conf
.
fm_coex
.
ldo_stabilization_time
);
acx
->
fm_disturbed_band_margin
=
wl
->
conf
.
fm_coex
.
fm_disturbed_band_margin
;
acx
->
swallow_clk_diff
=
wl
->
conf
.
fm_coex
.
swallow_clk_diff
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_FM_COEX_CFG
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx fm coex setting failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
drivers/net/wireless/wl12xx/acx.h
浏览文件 @
890641b2
...
...
@@ -303,7 +303,6 @@ struct acx_beacon_filter_option {
struct
acx_header
header
;
u8
enable
;
/*
* The number of beacons without the unicast TIM
* bit set that the firmware buffers before
...
...
@@ -370,14 +369,23 @@ struct acx_bt_wlan_coex {
u8
pad
[
3
];
}
__packed
;
struct
acx_bt_wlan_coex_param
{
struct
acx_
sta_
bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_PARAMS_MAX
];
__le32
params
[
CONF_SG_
STA_
PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_ap_bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_AP_PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_dco_itrim_params
{
struct
acx_header
header
;
...
...
@@ -1145,7 +1153,7 @@ struct wl1271_acx_fw_tsf_information {
u8
padding
[
3
];
}
__packed
;
struct
wl1271_acx_
ap_
max_tx_retry
{
struct
wl1271_acx_max_tx_retry
{
struct
acx_header
header
;
/*
...
...
@@ -1156,13 +1164,6 @@ struct wl1271_acx_ap_max_tx_retry {
u8
padding_1
[
2
];
}
__packed
;
struct
wl1271_acx_sta_max_tx_retry
{
struct
acx_header
header
;
u8
max_tx_retry
;
u8
padding_1
[
3
];
}
__packed
;
struct
wl1271_acx_config_ps
{
struct
acx_header
header
;
...
...
@@ -1179,6 +1180,72 @@ struct wl1271_acx_inconnection_sta {
u8
padding1
[
2
];
}
__packed
;
struct
acx_ap_beacon_filter
{
struct
acx_header
header
;
u8
enable
;
u8
pad
[
3
];
}
__packed
;
/*
* ACX_FM_COEX_CFG
* set the FM co-existence parameters.
*/
struct
wl1271_acx_fm_coex
{
struct
acx_header
header
;
/* enable(1) / disable(0) the FM Coex feature */
u8
enable
;
/*
* Swallow period used in COEX PLL swallowing mechanism.
* 0xFF = use FW default
*/
u8
swallow_period
;
/*
* The N divider used in COEX PLL swallowing mechanism for Fref of
* 38.4/19.2 Mhz. 0xFF = use FW default
*/
u8
n_divider_fref_set_1
;
/*
* The N divider used in COEX PLL swallowing mechanism for Fref of
* 26/52 Mhz. 0xFF = use FW default
*/
u8
n_divider_fref_set_2
;
/*
* The M divider used in COEX PLL swallowing mechanism for Fref of
* 38.4/19.2 Mhz. 0xFFFF = use FW default
*/
__le16
m_divider_fref_set_1
;
/*
* The M divider used in COEX PLL swallowing mechanism for Fref of
* 26/52 Mhz. 0xFFFF = use FW default
*/
__le16
m_divider_fref_set_2
;
/*
* The time duration in uSec required for COEX PLL to stabilize.
* 0xFFFFFFFF = use FW default
*/
__le32
coex_pll_stabilization_time
;
/*
* The time duration in uSec required for LDO to stabilize.
* 0xFFFFFFFF = use FW default
*/
__le16
ldo_stabilization_time
;
/*
* The disturbed frequency band margin around the disturbed frequency
* center (single sided).
* For example, if 2 is configured, the following channels will be
* considered disturbed channel:
* 80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
* 0xFF = use FW default
*/
u8
fm_disturbed_band_margin
;
/*
* The swallow clock difference of the swallowing mechanism.
* 0xFF = use FW default
*/
u8
swallow_clk_diff
;
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
...
...
@@ -1197,6 +1264,7 @@ enum {
ACX_TID_CFG
=
0x001A
,
ACX_PS_RX_STREAMING
=
0x001B
,
ACX_BEACON_FILTER_OPT
=
0x001F
,
ACX_AP_BEACON_FILTER_OPT
=
0x0020
,
ACX_NOISE_HIST
=
0x0021
,
ACX_HDK_VERSION
=
0x0022
,
/* ??? */
ACX_PD_THRESHOLD
=
0x0023
,
...
...
@@ -1208,6 +1276,7 @@ enum {
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
,
...
...
@@ -1264,13 +1333,14 @@ int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time);
int
wl1271_acx_group_address_tbl
(
struct
wl1271
*
wl
,
bool
enable
,
void
*
mc_list
,
u32
mc_list_len
);
int
wl1271_acx_service_period_timeout
(
struct
wl1271
*
wl
);
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
16
rts_threshold
);
int
wl1271_acx_rts_threshold
(
struct
wl1271
*
wl
,
u
32
rts_threshold
);
int
wl1271_acx_dco_itrim_params
(
struct
wl1271
*
wl
);
int
wl1271_acx_beacon_filter_opt
(
struct
wl1271
*
wl
,
bool
enable_filter
);
int
wl1271_acx_beacon_filter_table
(
struct
wl1271
*
wl
);
int
wl1271_acx_conn_monit_params
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_sg_enable
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_ap_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_cca_threshold
(
struct
wl1271
*
wl
);
int
wl1271_acx_bcn_dtim_options
(
struct
wl1271
*
wl
);
int
wl1271_acx_aid
(
struct
wl1271
*
wl
,
u16
aid
);
...
...
@@ -1287,7 +1357,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
int
wl1271_acx_tid_cfg
(
struct
wl1271
*
wl
,
u8
queue_id
,
u8
channel_type
,
u8
tsid
,
u8
ps_scheme
,
u8
ack_policy
,
u32
apsd_conf0
,
u32
apsd_conf1
);
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
16
frag_threshold
);
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u
32
frag_threshold
);
int
wl1271_acx_tx_config_options
(
struct
wl1271
*
wl
);
int
wl1271_acx_ap_mem_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_mem_cfg
(
struct
wl1271
*
wl
);
...
...
@@ -1314,9 +1384,10 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
int
wl1271_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
);
int
wl1271_acx_tsf_info
(
struct
wl1271
*
wl
,
u64
*
mactime
);
int
wl1271_acx_ap_max_tx_retry
(
struct
wl1271
*
wl
);
int
wl1271_acx_sta_max_tx_retry
(
struct
wl1271
*
wl
);
int
wl1271_acx_max_tx_retry
(
struct
wl1271
*
wl
);
int
wl1271_acx_config_ps
(
struct
wl1271
*
wl
);
int
wl1271_acx_set_inconnection_sta
(
struct
wl1271
*
wl
,
u8
*
addr
);
int
wl1271_acx_set_ap_beacon_filter
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_fm_coex
(
struct
wl1271
*
wl
);
#endif
/* __WL1271_ACX_H__ */
drivers/net/wireless/wl12xx/boot.c
浏览文件 @
890641b2
...
...
@@ -478,12 +478,10 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
DISCONNECT_EVENT_COMPLETE_ID
|
RSSI_SNR_TRIGGER_0_EVENT_ID
|
PSPOLL_DELIVERY_FAILURE_EVENT_ID
|
SOFT_GEMINI_SENSE_EVENT_ID
|
MAX_TX_RETRY_EVENT_ID
;
SOFT_GEMINI_SENSE_EVENT_ID
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
|
INACTIVE_STA_EVENT_ID
;
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
;
else
wl
->
event_mask
|=
DUMMY_PACKET_EVENT_ID
;
...
...
drivers/net/wireless/wl12xx/cmd.c
浏览文件 @
890641b2
...
...
@@ -76,7 +76,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
if
(
time_after
(
jiffies
,
timeout
))
{
wl1271_error
(
"command complete timeout"
);
ret
=
-
ETIMEDOUT
;
goto
out
;
goto
fail
;
}
poll_count
++
;
...
...
@@ -96,14 +96,17 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
status
=
le16_to_cpu
(
cmd
->
status
);
if
(
status
!=
CMD_STATUS_SUCCESS
)
{
wl1271_error
(
"command execute failure %d"
,
status
);
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
ret
=
-
EIO
;
goto
fail
;
}
wl1271_write32
(
wl
,
ACX_REG_INTERRUPT_ACK
,
WL1271_ACX_INTR_CMD_COMPLETE
);
return
0
;
out:
fail:
WARN_ON
(
1
);
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
return
ret
;
}
...
...
@@ -129,6 +132,9 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
if
(
gp
->
tx_bip_fem_auto_detect
)
answer
=
true
;
/* Override the REF CLK from the NVS with the one from platform data */
gen_parms
->
general_params
.
ref_clock
=
wl
->
ref_clock
;
ret
=
wl1271_cmd_test
(
wl
,
gen_parms
,
sizeof
(
*
gen_parms
),
answer
);
if
(
ret
<
0
)
{
wl1271_warning
(
"CMD_INI_FILE_GENERAL_PARAM failed"
);
...
...
@@ -168,6 +174,10 @@ int wl128x_cmd_general_parms(struct wl1271 *wl)
if
(
gp
->
tx_bip_fem_auto_detect
)
answer
=
true
;
/* Replace REF and TCXO CLKs with the ones from platform data */
gen_parms
->
general_params
.
ref_clock
=
wl
->
ref_clock
;
gen_parms
->
general_params
.
tcxo_ref_clock
=
wl
->
tcxo_clock
;
ret
=
wl1271_cmd_test
(
wl
,
gen_parms
,
sizeof
(
*
gen_parms
),
answer
);
if
(
ret
<
0
)
{
wl1271_warning
(
"CMD_INI_FILE_GENERAL_PARAM failed"
);
...
...
@@ -1070,7 +1080,7 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
memcpy
(
cmd
->
bssid
,
bss_conf
->
bssid
,
ETH_ALEN
);
cmd
->
aging_period
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_aging_period
);
cmd
->
aging_period
=
cpu_to_le16
(
WL1271_AP_DEF_INACTIV_SEC
);
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
global_hlid
=
WL1271_AP_GLOBAL_HLID
;
cmd
->
broadcast_hlid
=
WL1271_AP_BROADCAST_HLID
;
...
...
drivers/net/wireless/wl12xx/conf.h
浏览文件 @
890641b2
...
...
@@ -396,12 +396,43 @@ enum {
CONF_SG_TEMP_PARAM_3
,
CONF_SG_TEMP_PARAM_4
,
CONF_SG_TEMP_PARAM_5
,
CONF_SG_PARAMS_MAX
,
/*
* AP beacon miss
*
* Range: 0 - 255
*/
CONF_SG_AP_BEACON_MISS_TX
,
/*
* AP RX window length
*
* Range: 0 - 50
*/
CONF_SG_RX_WINDOW_LENGTH
,
/*
* AP connection protection time
*
* Range: 0 - 5000
*/
CONF_SG_AP_CONNECTION_PROTECTION_TIME
,
CONF_SG_TEMP_PARAM_6
,
CONF_SG_TEMP_PARAM_7
,
CONF_SG_TEMP_PARAM_8
,
CONF_SG_TEMP_PARAM_9
,
CONF_SG_TEMP_PARAM_10
,
CONF_SG_STA_PARAMS_MAX
=
CONF_SG_TEMP_PARAM_5
+
1
,
CONF_SG_AP_PARAMS_MAX
=
CONF_SG_TEMP_PARAM_10
+
1
,
CONF_SG_PARAMS_ALL
=
0xff
};
struct
conf_sg_settings
{
u32
params
[
CONF_SG_PARAMS_MAX
];
u32
sta_params
[
CONF_SG_STA_PARAMS_MAX
];
u32
ap_params
[
CONF_SG_AP_PARAMS_MAX
];
u8
state
;
};
...
...
@@ -509,6 +540,12 @@ struct conf_rx_settings {
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
#define CONF_TX_OFDM_RATES (CONF_HW_BIT_RATE_6MBPS | \
CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS | \
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
/*
* Default rates for management traffic when operating in AP mode. This
* should be configured according to the basic rate set of the AP
...
...
@@ -516,6 +553,13 @@ struct conf_rx_settings {
#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
/*
* Default rates for working as IBSS. use 11b rates
*/
#define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \
CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
CONF_HW_BIT_RATE_11MBPS);
struct
conf_tx_rate_class
{
/*
...
...
@@ -667,34 +711,10 @@ struct conf_tx_settings {
struct
conf_tx_ac_category
ac_conf
[
CONF_TX_MAX_AC_COUNT
];
/*
* Configuration for rate classes in AP-mode. These rate classes
* are for the AC TX queues
*/
struct
conf_tx_rate_class
ap_rc_conf
[
CONF_TX_MAX_AC_COUNT
];
/*
* Management TX rate class for AP-mode.
*/
struct
conf_tx_rate_class
ap_mgmt_conf
;
/*
* Broadcast TX rate class for AP-mode.
*/
struct
conf_tx_rate_class
ap_bcst_conf
;
/*
* Allow this number of TX retries to a connected station/AP before an
* AP-mode - allow this number of TX retries to a station before an
* event is triggered from FW.
* In AP-mode the hlids of unreachable stations are given in the
* "sta_tx_retry_exceeded" member in the event mailbox.
*/
u8
max_tx_retries
;
/*
* AP-mode - after this number of seconds a connected station is
* considered inactive.
*/
u16
ap_aging_period
;
u16
ap_max_tx_retries
;
/*
* Configuration for TID parameters.
...
...
@@ -1192,6 +1212,19 @@ struct conf_memory_settings {
u8
tx_min
;
};
struct
conf_fm_coex
{
u8
enable
;
u8
swallow_period
;
u8
n_divider_fref_set_1
;
u8
n_divider_fref_set_2
;
u16
m_divider_fref_set_1
;
u16
m_divider_fref_set_2
;
u32
coex_pll_stabilization_time
;
u16
ldo_stabilization_time
;
u8
fm_disturbed_band_margin
;
u8
swallow_clk_diff
;
};
struct
conf_drv_settings
{
struct
conf_sg_settings
sg
;
struct
conf_rx_settings
rx
;
...
...
@@ -1205,6 +1238,7 @@ struct conf_drv_settings {
struct
conf_ht_setting
ht
;
struct
conf_memory_settings
mem_wl127x
;
struct
conf_memory_settings
mem_wl128x
;
struct
conf_fm_coex
fm_coex
;
u8
hci_io_ds
;
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
浏览文件 @
890641b2
...
...
@@ -291,6 +291,241 @@ static const struct file_operations gpio_power_ops = {
.
llseek
=
default_llseek
,
};
static
ssize_t
start_recovery_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
mutex_lock
(
&
wl
->
mutex
);
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
recovery_work
);
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
start_recovery_ops
=
{
.
write
=
start_recovery_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
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
int
res
=
0
;
char
buf
[
1024
];
mutex_lock
(
&
wl
->
mutex
);
#define DRIVER_STATE_PRINT(x, fmt) \
(res += scnprintf(buf + res, sizeof(buf) - res,\
#x " = " fmt "\n", wl->x))
#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d")
#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s")
#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x")
DRIVER_STATE_PRINT_INT
(
tx_blocks_available
);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
);
DRIVER_STATE_PRINT_INT
(
tx_frames_cnt
);
DRIVER_STATE_PRINT_LHEX
(
tx_frames_map
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_queue_count
);
DRIVER_STATE_PRINT_INT
(
tx_packets_count
);
DRIVER_STATE_PRINT_INT
(
tx_results_count
);
DRIVER_STATE_PRINT_LHEX
(
flags
);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
1
]);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
2
]);
DRIVER_STATE_PRINT_INT
(
tx_blocks_freed
[
3
]);
DRIVER_STATE_PRINT_INT
(
tx_security_last_seq
);
DRIVER_STATE_PRINT_INT
(
rx_counter
);
DRIVER_STATE_PRINT_INT
(
session_counter
);
DRIVER_STATE_PRINT_INT
(
state
);
DRIVER_STATE_PRINT_INT
(
bss_type
);
DRIVER_STATE_PRINT_INT
(
channel
);
DRIVER_STATE_PRINT_HEX
(
rate_set
);
DRIVER_STATE_PRINT_HEX
(
basic_rate_set
);
DRIVER_STATE_PRINT_HEX
(
basic_rate
);
DRIVER_STATE_PRINT_INT
(
band
);
DRIVER_STATE_PRINT_INT
(
beacon_int
);
DRIVER_STATE_PRINT_INT
(
psm_entry_retry
);
DRIVER_STATE_PRINT_INT
(
ps_poll_failures
);
DRIVER_STATE_PRINT_HEX
(
filters
);
DRIVER_STATE_PRINT_HEX
(
rx_config
);
DRIVER_STATE_PRINT_HEX
(
rx_filter
);
DRIVER_STATE_PRINT_INT
(
power_level
);
DRIVER_STATE_PRINT_INT
(
rssi_thold
);
DRIVER_STATE_PRINT_INT
(
last_rssi_event
);
DRIVER_STATE_PRINT_INT
(
sg_enabled
);
DRIVER_STATE_PRINT_INT
(
enable_11a
);
DRIVER_STATE_PRINT_INT
(
noise
);
DRIVER_STATE_PRINT_LHEX
(
ap_hlid_map
[
0
]);
DRIVER_STATE_PRINT_INT
(
last_tx_hlid
);
DRIVER_STATE_PRINT_INT
(
ba_support
);
DRIVER_STATE_PRINT_HEX
(
ba_rx_bitmap
);
DRIVER_STATE_PRINT_HEX
(
ap_fw_ps_map
);
DRIVER_STATE_PRINT_LHEX
(
ap_ps_map
);
DRIVER_STATE_PRINT_HEX
(
quirks
);
DRIVER_STATE_PRINT_HEX
(
irq
);
DRIVER_STATE_PRINT_HEX
(
ref_clock
);
DRIVER_STATE_PRINT_HEX
(
tcxo_clock
);
DRIVER_STATE_PRINT_HEX
(
hw_pg_ver
);
DRIVER_STATE_PRINT_HEX
(
platform_quirks
);
DRIVER_STATE_PRINT_HEX
(
chip
.
id
);
DRIVER_STATE_PRINT_STR
(
chip
.
fw_ver_str
);
#undef DRIVER_STATE_PRINT_INT
#undef DRIVER_STATE_PRINT_LONG
#undef DRIVER_STATE_PRINT_HEX
#undef DRIVER_STATE_PRINT_LHEX
#undef DRIVER_STATE_PRINT_STR
#undef DRIVER_STATE_PRINT
mutex_unlock
(
&
wl
->
mutex
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
res
);
}
static
const
struct
file_operations
driver_state_ops
=
{
.
read
=
driver_state_read
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
ssize_t
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
.
wake_up_event
==
CONF_WAKE_UP_EVENT_DTIM
||
wl
->
conf
.
conn
.
wake_up_event
==
CONF_WAKE_UP_EVENT_N_DTIM
)
value
=
wl
->
conf
.
conn
.
listen_interval
;
else
value
=
0
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
value
);
}
static
ssize_t
dtim_interval_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for dtim_interval"
);
return
-
EINVAL
;
}
if
(
value
<
1
||
value
>
10
)
{
wl1271_warning
(
"dtim value is not in valid range"
);
return
-
ERANGE
;
}
mutex_lock
(
&
wl
->
mutex
);
wl
->
conf
.
conn
.
listen_interval
=
value
;
/* for some reason there are different event types for 1 and >1 */
if
(
value
==
1
)
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_DTIM
;
else
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_N_DTIM
;
/*
* we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
* take effect on the next time we enter psm.
*/
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
dtim_interval_ops
=
{
.
read
=
dtim_interval_read
,
.
write
=
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
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
u8
value
;
if
(
wl
->
conf
.
conn
.
wake_up_event
==
CONF_WAKE_UP_EVENT_BEACON
||
wl
->
conf
.
conn
.
wake_up_event
==
CONF_WAKE_UP_EVENT_N_BEACONS
)
value
=
wl
->
conf
.
conn
.
listen_interval
;
else
value
=
0
;
return
wl1271_format_buffer
(
user_buf
,
count
,
ppos
,
"%d
\n
"
,
value
);
}
static
ssize_t
beacon_interval_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for beacon_interval"
);
return
-
EINVAL
;
}
if
(
value
<
1
||
value
>
255
)
{
wl1271_warning
(
"beacon interval value is not in valid range"
);
return
-
ERANGE
;
}
mutex_lock
(
&
wl
->
mutex
);
wl
->
conf
.
conn
.
listen_interval
=
value
;
/* for some reason there are different event types for 1 and >1 */
if
(
value
==
1
)
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_BEACON
;
else
wl
->
conf
.
conn
.
wake_up_event
=
CONF_WAKE_UP_EVENT_N_BEACONS
;
/*
* we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
* take effect on the next time we enter psm.
*/
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
beacon_interval_ops
=
{
.
read
=
beacon_interval_read
,
.
write
=
beacon_interval_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
int
wl1271_debugfs_add_files
(
struct
wl1271
*
wl
,
struct
dentry
*
rootdir
)
{
...
...
@@ -399,6 +634,10 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD
(
excessive_retries
,
rootdir
);
DEBUGFS_ADD
(
gpio_power
,
rootdir
);
DEBUGFS_ADD
(
start_recovery
,
rootdir
);
DEBUGFS_ADD
(
driver_state
,
rootdir
);
DEBUGFS_ADD
(
dtim_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_interval
,
rootdir
);
return
0
;
...
...
drivers/net/wireless/wl12xx/event.c
浏览文件 @
890641b2
...
...
@@ -174,8 +174,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
u32
vector
;
bool
beacon_loss
=
false
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
bool
disconnect_sta
=
false
;
unsigned
long
sta_bitmap
=
0
;
wl1271_event_mbox_dump
(
mbox
);
...
...
@@ -237,54 +235,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_tx_dummy_packet
(
wl
);
}
/*
* "TX retries exceeded" has a different meaning according to mode.
* In AP mode the offending station is disconnected. In STA mode we
* report connection loss.
*/
if
(
vector
&
MAX_TX_RETRY_EVENT_ID
)
{
wl1271_debug
(
DEBUG_EVENT
,
"MAX_TX_RETRY_EVENT_ID"
);
if
(
is_ap
)
{
sta_bitmap
|=
le16_to_cpu
(
mbox
->
sta_tx_retry_exceeded
);
disconnect_sta
=
true
;
}
else
{
beacon_loss
=
true
;
}
}
if
((
vector
&
INACTIVE_STA_EVENT_ID
)
&&
is_ap
)
{
wl1271_debug
(
DEBUG_EVENT
,
"INACTIVE_STA_EVENT_ID"
);
sta_bitmap
|=
le16_to_cpu
(
mbox
->
sta_aging_status
);
disconnect_sta
=
true
;
}
if
(
wl
->
vif
&&
beacon_loss
)
ieee80211_connection_loss
(
wl
->
vif
);
if
(
is_ap
&&
disconnect_sta
)
{
u32
num_packets
=
wl
->
conf
.
tx
.
max_tx_retries
;
struct
ieee80211_sta
*
sta
;
const
u8
*
addr
;
int
h
;
for
(
h
=
find_first_bit
(
&
sta_bitmap
,
AP_MAX_LINKS
);
h
<
AP_MAX_LINKS
;
h
=
find_next_bit
(
&
sta_bitmap
,
AP_MAX_LINKS
,
h
+
1
))
{
if
(
!
wl1271_is_active_sta
(
wl
,
h
))
continue
;
addr
=
wl
->
links
[
h
].
addr
;
rcu_read_lock
();
sta
=
ieee80211_find_sta
(
wl
->
vif
,
addr
);
if
(
sta
)
{
wl1271_debug
(
DEBUG_EVENT
,
"remove sta %d"
,
h
);
ieee80211_report_low_ack
(
sta
,
num_packets
);
}
rcu_read_unlock
();
}
}
return
0
;
}
...
...
drivers/net/wireless/wl12xx/event.h
浏览文件 @
890641b2
...
...
@@ -58,16 +58,13 @@ enum {
CHANNEL_SWITCH_COMPLETE_EVENT_ID
=
BIT
(
17
),
BSS_LOSE_EVENT_ID
=
BIT
(
18
),
REGAINED_BSS_EVENT_ID
=
BIT
(
19
),
MAX_TX_RETRY_EVENT_ID
=
BIT
(
20
),
ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID
=
BIT
(
20
),
/* STA: dummy paket for dynamic mem blocks */
DUMMY_PACKET_EVENT_ID
=
BIT
(
21
),
/* AP: STA remove complete */
STA_REMOVE_COMPLETE_EVENT_ID
=
BIT
(
21
),
SOFT_GEMINI_SENSE_EVENT_ID
=
BIT
(
22
),
/* STA: SG prediction */
SOFT_GEMINI_PREDICTION_EVENT_ID
=
BIT
(
23
),
/* AP: Inactive STA */
INACTIVE_STA_EVENT_ID
=
BIT
(
23
),
SOFT_GEMINI_AVALANCHE_EVENT_ID
=
BIT
(
24
),
PLT_RX_CALIBRATION_COMPLETE_EVENT_ID
=
BIT
(
25
),
DBG_EVENT_ID
=
BIT
(
26
),
...
...
@@ -122,11 +119,7 @@ struct event_mailbox {
/* AP FW only */
u8
hlid_removed
;
/* a bitmap of hlids for stations that have been inactive too long */
__le16
sta_aging_status
;
/* a bitmap of hlids for stations which didn't respond to TX */
__le16
sta_tx_retry_exceeded
;
u8
reserved_5
[
24
];
...
...
@@ -137,7 +130,4 @@ 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
);
/* Functions from main.c */
bool
wl1271_is_active_sta
(
struct
wl1271
*
wl
,
u8
hlid
);
#endif
drivers/net/wireless/wl12xx/init.c
浏览文件 @
890641b2
...
...
@@ -258,7 +258,7 @@ int wl1271_init_phy_config(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_rts_threshold
(
wl
,
wl
->
conf
.
rx
.
rts_threshold
);
ret
=
wl1271_acx_rts_threshold
(
wl
,
wl
->
hw
->
wiphy
->
rts_threshold
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -285,7 +285,10 @@ int wl1271_init_pta(struct wl1271 *wl)
{
int
ret
;
ret
=
wl1271_acx_sg_cfg
(
wl
);
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
ret
=
wl1271_acx_ap_sg_cfg
(
wl
);
else
ret
=
wl1271_acx_sta_sg_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -351,8 +354,8 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/*
Bluetooth
WLAN coexistence */
ret
=
wl1271_
init_pta
(
wl
);
/*
FM
WLAN coexistence */
ret
=
wl1271_
acx_fm_coex
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -375,10 +378,6 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_sta_max_tx_retry
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_sta_mem_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -414,7 +413,7 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
static
int
wl1271_ap_hw_init
(
struct
wl1271
*
wl
)
{
int
ret
,
i
;
int
ret
;
ret
=
wl1271_ap_init_templates_config
(
wl
);
if
(
ret
<
0
)
...
...
@@ -425,27 +424,11 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/* Configure initial TX rate classes */
for
(
i
=
0
;
i
<
wl
->
conf
.
tx
.
ac_conf_count
;
i
++
)
{
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_rc_conf
[
i
],
i
);
if
(
ret
<
0
)
return
ret
;
}
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_mgmt_conf
,
ACX_TX_AP_MODE_MGMT_RATE
);
ret
=
wl1271_init_ap_rates
(
wl
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
wl
->
conf
.
tx
.
ap_bcst_conf
,
ACX_TX_AP_MODE_BCST_RATE
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_ap_max_tx_retry
(
wl
);
ret
=
wl1271_acx_max_tx_retry
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -456,7 +439,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
return
0
;
}
static
int
wl1271_ap_hw_init_post_mem
(
struct
wl1271
*
wl
)
int
wl1271_ap_init_templates
(
struct
wl1271
*
wl
)
{
int
ret
;
...
...
@@ -472,6 +455,70 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/*
* when operating as AP we want to receive external beacons for
* configuring ERP protection.
*/
ret
=
wl1271_acx_set_ap_beacon_filter
(
wl
,
false
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
static
int
wl1271_ap_hw_init_post_mem
(
struct
wl1271
*
wl
)
{
return
wl1271_ap_init_templates
(
wl
);
}
int
wl1271_init_ap_rates
(
struct
wl1271
*
wl
)
{
int
i
,
ret
;
struct
conf_tx_rate_class
rc
;
u32
supported_rates
;
wl1271_debug
(
DEBUG_AP
,
"AP basic rate set: 0x%x"
,
wl
->
basic_rate_set
);
if
(
wl
->
basic_rate_set
==
0
)
return
-
EINVAL
;
rc
.
enabled_rates
=
wl
->
basic_rate_set
;
rc
.
long_retry_limit
=
10
;
rc
.
short_retry_limit
=
10
;
rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
rc
,
ACX_TX_AP_MODE_MGMT_RATE
);
if
(
ret
<
0
)
return
ret
;
/* use the min basic rate for AP broadcast/multicast */
rc
.
enabled_rates
=
wl1271_tx_min_rate_get
(
wl
);
rc
.
short_retry_limit
=
10
;
rc
.
long_retry_limit
=
10
;
rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
rc
,
ACX_TX_AP_MODE_BCST_RATE
);
if
(
ret
<
0
)
return
ret
;
/*
* If the basic rates contain OFDM rates, use OFDM only
* rates for unicast TX as well. Else use all supported rates.
*/
if
((
wl
->
basic_rate_set
&
CONF_TX_OFDM_RATES
))
supported_rates
=
CONF_TX_OFDM_RATES
;
else
supported_rates
=
CONF_TX_AP_ENABLED_RATES
;
/* configure unicast TX rate classes */
for
(
i
=
0
;
i
<
wl
->
conf
.
tx
.
ac_conf_count
;
i
++
)
{
rc
.
enabled_rates
=
supported_rates
;
rc
.
short_retry_limit
=
10
;
rc
.
long_retry_limit
=
10
;
rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
rc
,
i
);
if
(
ret
<
0
)
return
ret
;
}
return
0
;
}
...
...
@@ -567,6 +614,11 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
/* Bluetooth WLAN coexistence */
ret
=
wl1271_init_pta
(
wl
);
if
(
ret
<
0
)
return
ret
;
/* Default memory configuration */
ret
=
wl1271_acx_init_mem_config
(
wl
);
if
(
ret
<
0
)
...
...
@@ -606,7 +658,7 @@ int wl1271_hw_init(struct wl1271 *wl)
goto
out_free_memmap
;
/* Default fragmentation threshold */
ret
=
wl1271_acx_frag_threshold
(
wl
,
wl
->
conf
.
tx
.
frag_threshold
);
ret
=
wl1271_acx_frag_threshold
(
wl
,
wl
->
hw
->
wiphy
->
frag_threshold
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
drivers/net/wireless/wl12xx/init.h
浏览文件 @
890641b2
...
...
@@ -33,5 +33,7 @@ int wl1271_init_pta(struct wl1271 *wl);
int
wl1271_init_energy_detection
(
struct
wl1271
*
wl
);
int
wl1271_chip_specific_init
(
struct
wl1271
*
wl
);
int
wl1271_hw_init
(
struct
wl1271
*
wl
);
int
wl1271_init_ap_rates
(
struct
wl1271
*
wl
);
int
wl1271_ap_init_templates
(
struct
wl1271
*
wl
);
#endif
drivers/net/wireless/wl12xx/main.c
浏览文件 @
890641b2
...
...
@@ -51,7 +51,7 @@
static
struct
conf_drv_settings
default_conf
=
{
.
sg
=
{
.
params
=
{
.
sta_
params
=
{
[
CONF_SG_BT_PER_THRESHOLD
]
=
7500
,
[
CONF_SG_HV3_MAX_OVERRIDE
]
=
0
,
[
CONF_SG_BT_NFS_SAMPLE_INTERVAL
]
=
400
,
...
...
@@ -101,6 +101,61 @@ static struct conf_drv_settings default_conf = {
[
CONF_SG_DHCP_TIME
]
=
5000
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
]
=
100
,
},
.
ap_params
=
{
[
CONF_SG_BT_PER_THRESHOLD
]
=
7500
,
[
CONF_SG_HV3_MAX_OVERRIDE
]
=
0
,
[
CONF_SG_BT_NFS_SAMPLE_INTERVAL
]
=
400
,
[
CONF_SG_BT_LOAD_RATIO
]
=
50
,
[
CONF_SG_AUTO_PS_MODE
]
=
1
,
[
CONF_SG_AUTO_SCAN_PROBE_REQ
]
=
170
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3
]
=
50
,
[
CONF_SG_ANTENNA_CONFIGURATION
]
=
0
,
[
CONF_SG_BEACON_MISS_PERCENT
]
=
60
,
[
CONF_SG_RATE_ADAPT_THRESH
]
=
64
,
[
CONF_SG_RATE_ADAPT_SNR
]
=
1
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR
]
=
10
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR
]
=
25
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR
]
=
20
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR
]
=
25
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR
]
=
7
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR
]
=
25
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR
]
=
8
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR
]
=
25
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR
]
=
25
,
[
CONF_SG_RXT
]
=
1200
,
[
CONF_SG_TXT
]
=
1000
,
[
CONF_SG_ADAPTIVE_RXT_TXT
]
=
1
,
[
CONF_SG_PS_POLL_TIMEOUT
]
=
10
,
[
CONF_SG_UPSD_TIMEOUT
]
=
10
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR
]
=
7
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR
]
=
8
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR
]
=
20
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR
]
=
15
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR
]
=
20
,
[
CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR
]
=
50
,
[
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR
]
=
10
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
]
=
200
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP
]
=
800
,
[
CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME
]
=
75
,
[
CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME
]
=
15
,
[
CONF_SG_HV3_MAX_SERVED
]
=
6
,
[
CONF_SG_DHCP_TIME
]
=
5000
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
]
=
100
,
[
CONF_SG_TEMP_PARAM_1
]
=
0
,
[
CONF_SG_TEMP_PARAM_2
]
=
0
,
[
CONF_SG_TEMP_PARAM_3
]
=
0
,
[
CONF_SG_TEMP_PARAM_4
]
=
0
,
[
CONF_SG_TEMP_PARAM_5
]
=
0
,
[
CONF_SG_AP_BEACON_MISS_TX
]
=
3
,
[
CONF_SG_RX_WINDOW_LENGTH
]
=
6
,
[
CONF_SG_AP_CONNECTION_PROTECTION_TIME
]
=
50
,
[
CONF_SG_TEMP_PARAM_6
]
=
1
,
},
.
state
=
CONF_SG_PROTECTIVE
,
},
.
rx
=
{
...
...
@@ -108,7 +163,7 @@ static struct conf_drv_settings default_conf = {
.
packet_detection_threshold
=
0
,
.
ps_poll_timeout
=
15
,
.
upsd_timeout
=
15
,
.
rts_threshold
=
2347
,
.
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
,
.
rx_cca_threshold
=
0
,
.
irq_blk_threshold
=
0xFFFF
,
.
irq_pkt_threshold
=
0
,
...
...
@@ -154,46 +209,7 @@ static struct conf_drv_settings default_conf = {
.
tx_op_limit
=
1504
,
},
},
.
ap_rc_conf
=
{
[
0
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
[
1
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
[
2
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
[
3
]
=
{
.
enabled_rates
=
CONF_TX_AP_ENABLED_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
},
.
ap_mgmt_conf
=
{
.
enabled_rates
=
CONF_TX_AP_DEFAULT_MGMT_RATES
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
.
ap_bcst_conf
=
{
.
enabled_rates
=
CONF_HW_BIT_RATE_1MBPS
,
.
short_retry_limit
=
10
,
.
long_retry_limit
=
10
,
.
aflags
=
0
,
},
.
max_tx_retries
=
100
,
.
ap_aging_period
=
300
,
.
ap_max_tx_retries
=
100
,
.
tid_conf_count
=
4
,
.
tid_conf
=
{
[
CONF_TX_AC_BE
]
=
{
...
...
@@ -258,7 +274,7 @@ static struct conf_drv_settings default_conf = {
.
bet_enable
=
CONF_BET_MODE_ENABLE
,
.
bet_max_consecutive
=
50
,
.
psm_entry_retries
=
5
,
.
psm_exit_retries
=
255
,
.
psm_exit_retries
=
16
,
.
psm_entry_nullfunc_retries
=
3
,
.
psm_entry_hangover_period
=
1
,
.
keep_alive_interval
=
55000
,
...
...
@@ -305,7 +321,7 @@ static struct conf_drv_settings default_conf = {
.
ssid_profiles
=
1
,
.
rx_block_num
=
70
,
.
tx_min_block_num
=
40
,
.
dynamic_memory
=
0
,
.
dynamic_memory
=
1
,
.
min_req_tx_blocks
=
100
,
.
min_req_rx_blocks
=
22
,
.
tx_min
=
27
,
...
...
@@ -320,10 +336,23 @@ static struct conf_drv_settings default_conf = {
.
min_req_rx_blocks
=
22
,
.
tx_min
=
27
,
},
.
fm_coex
=
{
.
enable
=
true
,
.
swallow_period
=
5
,
.
n_divider_fref_set_1
=
0xff
,
/* default */
.
n_divider_fref_set_2
=
12
,
.
m_divider_fref_set_1
=
148
,
.
m_divider_fref_set_2
=
0xffff
,
/* default */
.
coex_pll_stabilization_time
=
0xffffffff
,
/* default */
.
ldo_stabilization_time
=
0xffff
,
/* default */
.
fm_disturbed_band_margin
=
0xff
,
/* default */
.
swallow_clk_diff
=
0xff
,
/* default */
},
.
hci_io_ds
=
HCI_IO_DS_6MA
,
};
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
);
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
);
static
void
wl1271_free_ap_keys
(
struct
wl1271
*
wl
);
...
...
@@ -508,6 +537,11 @@ static int wl1271_plt_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
/* FM WLAN coexistence */
ret
=
wl1271_acx_fm_coex
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Energy detection */
ret
=
wl1271_init_energy_detection
(
wl
);
if
(
ret
<
0
)
...
...
@@ -932,15 +966,25 @@ static void wl1271_recovery_work(struct work_struct *work)
if
(
wl
->
state
!=
WL1271_STATE_ON
)
goto
out
;
wl1271_info
(
"Hardware recovery in progress."
);
wl1271_info
(
"Hardware recovery in progress. FW ver: %s pc: 0x%x"
,
wl
->
chip
.
fw_ver_str
,
wl1271_read32
(
wl
,
SCR_PAD4
));
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
ieee80211_connection_loss
(
wl
->
vif
);
/* Prevent spurious TX during FW restart */
ieee80211_stop_queues
(
wl
->
hw
);
/* reboot the chipset */
__wl1271_op_remove_interface
(
wl
);
__wl1271_op_remove_interface
(
wl
,
false
);
ieee80211_restart_hw
(
wl
->
hw
);
/*
* Its safe to enable TX now - the queues are stopped after a request
* to restart the HW.
*/
ieee80211_wake_queues
(
wl
->
hw
);
out:
mutex_unlock
(
&
wl
->
mutex
);
}
...
...
@@ -1011,6 +1055,10 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
wl1271_debug
(
DEBUG_BOOT
,
"chip id 0x%x (1271 PG20)"
,
wl
->
chip
.
id
);
/* end-of-transaction flag should be set in wl127x AP mode */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
ret
=
wl1271_setup
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -1273,7 +1321,7 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
skb
->
priority
=
WL1271_TID_MGMT
;
/* Initialize all fields that might be used */
skb
->
queue_mapping
=
0
;
skb
_set_queue_mapping
(
skb
,
0
)
;
memset
(
IEEE80211_SKB_CB
(
skb
),
0
,
sizeof
(
struct
ieee80211_tx_info
));
return
skb
;
...
...
@@ -1440,7 +1488,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
return
ret
;
}
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
)
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
)
{
int
i
;
...
...
@@ -1486,7 +1535,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
mutex_lock
(
&
wl
->
mutex
);
/* let's notify MAC80211 about the remaining pending TX frames */
wl1271_tx_reset
(
wl
);
wl1271_tx_reset
(
wl
,
reset_tx_queues
);
wl1271_power_off
(
wl
);
memset
(
wl
->
bssid
,
0
,
ETH_ALEN
);
...
...
@@ -1547,7 +1596,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
*/
if
(
wl
->
vif
)
{
WARN_ON
(
wl
->
vif
!=
vif
);
__wl1271_op_remove_interface
(
wl
);
__wl1271_op_remove_interface
(
wl
,
true
);
}
mutex_unlock
(
&
wl
->
mutex
);
...
...
@@ -2284,7 +2333,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_acx_frag_threshold
(
wl
,
(
u16
)
value
);
ret
=
wl1271_acx_frag_threshold
(
wl
,
value
);
if
(
ret
<
0
)
wl1271_warning
(
"wl1271_op_set_frag_threshold failed: %d"
,
ret
);
...
...
@@ -2312,7 +2361,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_acx_rts_threshold
(
wl
,
(
u16
)
value
);
ret
=
wl1271_acx_rts_threshold
(
wl
,
value
);
if
(
ret
<
0
)
wl1271_warning
(
"wl1271_op_set_rts_threshold failed: %d"
,
ret
);
...
...
@@ -2455,24 +2504,19 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
if
((
changed
&
BSS_CHANGED_BASIC_RATES
))
{
u32
rates
=
bss_conf
->
basic_rates
;
struct
conf_tx_rate_class
mgmt_rc
;
wl
->
basic_rate_set
=
wl1271_tx_enabled_rates_get
(
wl
,
rates
);
wl
->
basic_rate
=
wl1271_tx_min_rate_get
(
wl
);
wl1271_debug
(
DEBUG_AP
,
"basic rates: 0x%x"
,
wl
->
basic_rate_set
);
/* update the AP management rate policy with the new rates */
mgmt_rc
.
enabled_rates
=
wl
->
basic_rate_set
;
mgmt_rc
.
long_retry_limit
=
10
;
mgmt_rc
.
short_retry_limit
=
10
;
mgmt_rc
.
aflags
=
0
;
ret
=
wl1271_acx_ap_rate_policy
(
wl
,
&
mgmt_rc
,
ACX_TX_AP_MODE_MGMT_RATE
);
ret
=
wl1271_init_ap_rates
(
wl
);
if
(
ret
<
0
)
{
wl1271_error
(
"AP
mgmt
policy change failed %d"
,
ret
);
wl1271_error
(
"AP
rate
policy change failed %d"
,
ret
);
goto
out
;
}
ret
=
wl1271_ap_init_templates
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
ret
=
wl1271_bss_beacon_info_changed
(
wl
,
vif
,
bss_conf
,
changed
);
...
...
@@ -2505,6 +2549,24 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
}
}
if
(
changed
&
BSS_CHANGED_IBSS
)
{
wl1271_debug
(
DEBUG_ADHOC
,
"ibss_joined: %d"
,
bss_conf
->
ibss_joined
);
if
(
bss_conf
->
ibss_joined
)
{
u32
rates
=
bss_conf
->
basic_rates
;
wl
->
basic_rate_set
=
wl1271_tx_enabled_rates_get
(
wl
,
rates
);
wl
->
basic_rate
=
wl1271_tx_min_rate_get
(
wl
);
/* by default, use 11b rates */
wl
->
rate_set
=
CONF_TX_IBSS_DEFAULT_RATES
;
ret
=
wl1271_acx_sta_rate_policies
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
}
ret
=
wl1271_bss_erp_info_changed
(
wl
,
bss_conf
,
changed
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -2694,8 +2756,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
}
}
else
{
/* use defaults when not associated */
bool
was_assoc
=
!!
test_and_clear_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
clear_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
);
clear_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
wl
->
aid
=
0
;
/* free probe-request template */
...
...
@@ -2721,8 +2785,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
goto
out
;
/* restore the bssid filter and go to dummy bssid */
wl1271_unjoin
(
wl
);
wl1271_dummy_join
(
wl
);
if
(
was_assoc
)
{
wl1271_unjoin
(
wl
);
wl1271_dummy_join
(
wl
);
}
}
}
...
...
@@ -2954,12 +3020,6 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
__clear_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
}
bool
wl1271_is_active_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
{
int
id
=
hlid
-
WL1271_AP_STA_HLID_START
;
return
test_bit
(
id
,
wl
->
ap_hlid_map
);
}
static
int
wl1271_op_sta_add
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
)
...
...
@@ -3104,6 +3164,28 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
return
ret
;
}
static
bool
wl1271_tx_frames_pending
(
struct
ieee80211_hw
*
hw
)
{
struct
wl1271
*
wl
=
hw
->
priv
;
bool
ret
=
false
;
mutex_lock
(
&
wl
->
mutex
);
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_OFF
))
goto
out
;
/* packets are considered pending if in the TX queue or the FW */
ret
=
(
wl
->
tx_queue_count
>
0
)
||
(
wl
->
tx_frames_cnt
>
0
);
/* the above is appropriate for STA mode for PS purposes */
WARN_ON
(
wl
->
bss_type
!=
BSS_TYPE_STA_BSS
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
ret
;
}
/* can't be const, mac80211 writes to this */
static
struct
ieee80211_rate
wl1271_rates
[]
=
{
{
.
bitrate
=
10
,
...
...
@@ -3355,6 +3437,7 @@ static const struct ieee80211_ops wl1271_ops = {
.
sta_add
=
wl1271_op_sta_add
,
.
sta_remove
=
wl1271_op_sta_remove
,
.
ampdu_action
=
wl1271_op_ampdu_action
,
.
tx_frames_pending
=
wl1271_tx_frames_pending
,
CFG80211_TESTMODE_CMD
(
wl1271_tm_cmd
)
};
...
...
@@ -3542,6 +3625,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
IEEE80211_HW_HAS_RATE_CONTROL
|
IEEE80211_HW_CONNECTION_MONITOR
|
IEEE80211_HW_SUPPORTS_CQM_RSSI
|
IEEE80211_HW_REPORTS_TX_ACK_STATUS
|
IEEE80211_HW_AP_LINK_PS
;
wl
->
hw
->
wiphy
->
cipher_suites
=
cipher_suites
;
...
...
drivers/net/wireless/wl12xx/ps.c
浏览文件 @
890641b2
...
...
@@ -43,6 +43,10 @@ void wl1271_elp_work(struct work_struct *work)
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_OFF
))
goto
out
;
/* our work might have been already cancelled */
if
(
unlikely
(
!
test_bit
(
WL1271_FLAG_ELP_REQUESTED
,
&
wl
->
flags
)))
goto
out
;
if
(
test_bit
(
WL1271_FLAG_IN_ELP
,
&
wl
->
flags
)
||
(
!
test_bit
(
WL1271_FLAG_PSM
,
&
wl
->
flags
)
&&
!
test_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
)))
...
...
@@ -61,12 +65,16 @@ void wl1271_elp_work(struct work_struct *work)
/* Routines to toggle sleep mode while in ELP */
void
wl1271_ps_elp_sleep
(
struct
wl1271
*
wl
)
{
if
(
test_bit
(
WL1271_FLAG_PSM
,
&
wl
->
flags
)
||
test_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
))
{
cancel_delayed_work
(
&
wl
->
elp_work
);
ieee80211_queue_delayed_work
(
wl
->
hw
,
&
wl
->
elp_work
,
msecs_to_jiffies
(
ELP_ENTRY_DELAY
));
}
/* we shouldn't get consecutive sleep requests */
if
(
WARN_ON
(
test_and_set_bit
(
WL1271_FLAG_ELP_REQUESTED
,
&
wl
->
flags
)))
return
;
if
(
!
test_bit
(
WL1271_FLAG_PSM
,
&
wl
->
flags
)
&&
!
test_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
))
return
;
ieee80211_queue_delayed_work
(
wl
->
hw
,
&
wl
->
elp_work
,
msecs_to_jiffies
(
ELP_ENTRY_DELAY
));
}
int
wl1271_ps_elp_wakeup
(
struct
wl1271
*
wl
)
...
...
@@ -77,6 +85,16 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
u32
start_time
=
jiffies
;
bool
pending
=
false
;
/*
* we might try to wake up even if we didn't go to sleep
* before (e.g. on boot)
*/
if
(
!
test_and_clear_bit
(
WL1271_FLAG_ELP_REQUESTED
,
&
wl
->
flags
))
return
0
;
/* don't cancel_sync as it might contend for a mutex and deadlock */
cancel_delayed_work
(
&
wl
->
elp_work
);
if
(
!
test_bit
(
WL1271_FLAG_IN_ELP
,
&
wl
->
flags
))
return
0
;
...
...
drivers/net/wireless/wl12xx/rx.c
浏览文件 @
890641b2
...
...
@@ -76,12 +76,15 @@ static void wl1271_rx_status(struct wl1271 *wl,
status
->
band
);
if
(
desc
->
flags
&
WL1271_RX_DESC_ENCRYPT_MASK
)
{
status
->
flag
|=
RX_FLAG_IV_STRIPPED
|
RX_FLAG_MMIC_STRIPPED
;
u8
desc_err_code
=
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
;
if
(
likely
(
!
(
desc
->
status
&
WL1271_RX_DESC_DECRYPT_FAIL
)))
status
->
flag
|=
RX_FLAG_DECRYPTED
;
if
(
unlikely
(
desc
->
status
&
WL1271_RX_DESC_MIC_FAIL
))
status
->
flag
|=
RX_FLAG_IV_STRIPPED
|
RX_FLAG_MMIC_STRIPPED
|
RX_FLAG_DECRYPTED
;
if
(
unlikely
(
desc_err_code
==
WL1271_RX_DESC_MIC_FAIL
))
{
status
->
flag
|=
RX_FLAG_MMIC_ERROR
;
wl1271_warning
(
"Michael MIC error"
);
}
}
}
...
...
@@ -100,6 +103,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
if
(
unlikely
(
wl
->
state
==
WL1271_STATE_PLT
))
return
-
EINVAL
;
/* the data read starts with the descriptor */
desc
=
(
struct
wl1271_rx_descriptor
*
)
data
;
switch
(
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
)
{
/* discard corrupted packets */
case
WL1271_RX_DESC_DRIVER_RX_Q_FAIL
:
case
WL1271_RX_DESC_DECRYPT_FAIL
:
wl1271_warning
(
"corrupted packet in RX with status: 0x%x"
,
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
);
return
-
EINVAL
;
case
WL1271_RX_DESC_SUCCESS
:
case
WL1271_RX_DESC_MIC_FAIL
:
break
;
default:
wl1271_error
(
"invalid RX descriptor status: 0x%x"
,
desc
->
status
&
WL1271_RX_DESC_STATUS_MASK
);
return
-
EINVAL
;
}
skb
=
__dev_alloc_skb
(
length
,
GFP_KERNEL
);
if
(
!
skb
)
{
wl1271_error
(
"Couldn't allocate RX frame"
);
...
...
@@ -109,9 +131,6 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
buf
=
skb_put
(
skb
,
length
);
memcpy
(
buf
,
data
,
length
);
/* the data read starts with the descriptor */
desc
=
(
struct
wl1271_rx_descriptor
*
)
buf
;
/* now we pull the descriptor out of the buffer */
skb_pull
(
skb
,
sizeof
(
*
desc
));
...
...
@@ -121,7 +140,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
wl1271_rx_status
(
wl
,
desc
,
IEEE80211_SKB_RXCB
(
skb
),
beacon
);
wl1271_debug
(
DEBUG_RX
,
"rx skb 0x%p: %d B %s"
,
skb
,
skb
->
len
,
wl1271_debug
(
DEBUG_RX
,
"rx skb 0x%p: %d B %s"
,
skb
,
skb
->
len
-
desc
->
pad_len
,
beacon
?
"beacon"
:
""
);
skb_trim
(
skb
,
skb
->
len
-
desc
->
pad_len
);
...
...
drivers/net/wireless/wl12xx/tx.c
浏览文件 @
890641b2
...
...
@@ -65,6 +65,9 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
static
void
wl1271_free_tx_id
(
struct
wl1271
*
wl
,
int
id
)
{
if
(
__test_and_clear_bit
(
id
,
wl
->
tx_frames_map
))
{
if
(
unlikely
(
wl
->
tx_frames_cnt
==
ACX_TX_DESCRIPTORS
))
clear_bit
(
WL1271_FLAG_FW_TX_BUSY
,
&
wl
->
flags
);
wl
->
tx_frames
[
id
]
=
NULL
;
wl
->
tx_frames_cnt
--
;
}
...
...
@@ -630,7 +633,7 @@ void wl1271_tx_work(struct work_struct *work)
wl1271_tx_work_locked
(
wl
);
wl1271_ps_elp_
wakeu
p
(
wl
);
wl1271_ps_elp_
slee
p
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
}
...
...
@@ -766,8 +769,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
wl1271_handle_tx_low_watermark
(
wl
);
}
/* caller must hold wl->mutex */
void
wl1271_tx_reset
(
struct
wl1271
*
wl
)
/* caller must hold wl->mutex
and TX must be stopped
*/
void
wl1271_tx_reset
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
)
{
int
i
;
struct
sk_buff
*
skb
;
...
...
@@ -803,8 +806,10 @@ void wl1271_tx_reset(struct wl1271 *wl)
/*
* Make sure the driver is at a consistent state, in case this
* function is called from a context other than interface removal.
* This call will always wake the TX queues.
*/
wl1271_handle_tx_low_watermark
(
wl
);
if
(
reset_tx_queues
)
wl1271_handle_tx_low_watermark
(
wl
);
for
(
i
=
0
;
i
<
ACX_TX_DESCRIPTORS
;
i
++
)
{
if
(
wl
->
tx_frames
[
i
]
==
NULL
)
...
...
drivers/net/wireless/wl12xx/tx.h
浏览文件 @
890641b2
...
...
@@ -185,7 +185,7 @@ static inline int wl1271_tx_get_queue(int queue)
void
wl1271_tx_work
(
struct
work_struct
*
work
);
void
wl1271_tx_work_locked
(
struct
wl1271
*
wl
);
void
wl1271_tx_complete
(
struct
wl1271
*
wl
);
void
wl1271_tx_reset
(
struct
wl1271
*
wl
);
void
wl1271_tx_reset
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
);
void
wl1271_tx_flush
(
struct
wl1271
*
wl
);
u8
wl1271_rate_to_idx
(
int
rate
,
enum
ieee80211_band
band
);
u32
wl1271_tx_enabled_rates_get
(
struct
wl1271
*
wl
,
u32
rate_set
);
...
...
drivers/net/wireless/wl12xx/wl12xx.h
浏览文件 @
890641b2
...
...
@@ -172,6 +172,7 @@ extern u32 wl12xx_debug_level;
#define WL1271_PS_STA_MAX_BLOCKS (2 * 9)
#define WL1271_AP_BSS_INDEX 0
#define WL1271_AP_DEF_INACTIV_SEC 300
#define WL1271_AP_DEF_BEACON_EXP 20
#define ACX_TX_DESCRIPTORS 32
...
...
@@ -345,6 +346,7 @@ enum wl12xx_flags {
WL1271_FLAG_TX_QUEUE_STOPPED
,
WL1271_FLAG_TX_PENDING
,
WL1271_FLAG_IN_ELP
,
WL1271_FLAG_ELP_REQUESTED
,
WL1271_FLAG_PSM
,
WL1271_FLAG_PSM_REQUESTED
,
WL1271_FLAG_IRQ_RUNNING
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录