Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
e0a8c583
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
e0a8c583
编写于
8月 29, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
上级
a508a6ea
04b4d69c
变更
25
隐藏空白更改
内联
并排
Showing
25 changed file
with
2090 addition
and
1860 deletion
+2090
-1860
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+123
-199
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+135
-259
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.c
+15
-28
drivers/net/wireless/wl12xx/boot.h
drivers/net/wireless/wl12xx/boot.h
+2
-1
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+587
-206
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+181
-148
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+140
-212
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+6
-11
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+3
-3
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/event.h
+31
-49
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+30
-61
drivers/net/wireless/wl12xx/io.h
drivers/net/wireless/wl12xx/io.h
+0
-1
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+582
-379
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+2
-2
drivers/net/wireless/wl12xx/reg.h
drivers/net/wireless/wl12xx/reg.h
+0
-75
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+36
-24
drivers/net/wireless/wl12xx/rx.h
drivers/net/wireless/wl12xx/rx.h
+8
-10
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.c
+28
-10
drivers/net/wireless/wl12xx/scan.h
drivers/net/wireless/wl12xx/scan.h
+16
-9
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/sdio.c
+1
-3
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/spi.c
+1
-3
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+84
-52
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+5
-11
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+74
-79
drivers/net/wireless/wl12xx/wl12xx_80211.h
drivers/net/wireless/wl12xx/wl12xx_80211.h
+0
-25
未找到文件。
drivers/net/wireless/wl12xx/acx.c
浏览文件 @
e0a8c583
...
...
@@ -46,6 +46,7 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl)
goto
out
;
}
wake_up
->
role_id
=
wl
->
role_id
;
wake_up
->
wake_up_event
=
wl
->
conf
.
conn
.
wake_up_event
;
wake_up
->
listen_interval
=
wl
->
conf
.
conn
.
listen_interval
;
...
...
@@ -101,6 +102,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
current_tx_power
=
power
*
10
;
ret
=
wl1271_cmd_configure
(
wl
,
DOT11_CUR_TX_PWR
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -128,6 +130,7 @@ int wl1271_acx_feature_cfg(struct wl1271 *wl)
}
/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
feature
->
role_id
=
wl
->
role_id
;
feature
->
data_flow_options
=
0
;
feature
->
options
=
0
;
...
...
@@ -183,34 +186,6 @@ int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl)
return
ret
;
}
int
wl1271_acx_rx_config
(
struct
wl1271
*
wl
,
u32
config
,
u32
filter
)
{
struct
acx_rx_config
*
rx_config
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx rx config"
);
rx_config
=
kzalloc
(
sizeof
(
*
rx_config
),
GFP_KERNEL
);
if
(
!
rx_config
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
rx_config
->
config_options
=
cpu_to_le32
(
config
);
rx_config
->
filter_options
=
cpu_to_le32
(
filter
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_RX_CFG
,
rx_config
,
sizeof
(
*
rx_config
));
if
(
ret
<
0
)
{
wl1271_warning
(
"failed to set rx config: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
rx_config
);
return
ret
;
}
int
wl1271_acx_pd_threshold
(
struct
wl1271
*
wl
)
{
struct
acx_packet_detection
*
pd
;
...
...
@@ -250,6 +225,7 @@ int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
goto
out
;
}
slot
->
role_id
=
wl
->
role_id
;
slot
->
wone_index
=
STATION_WONE_INDEX
;
slot
->
slot_time
=
slot_time
;
...
...
@@ -279,6 +255,7 @@ int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
}
/* MAC filtering */
acx
->
role_id
=
wl
->
role_id
;
acx
->
enabled
=
enable
;
acx
->
num_groups
=
mc_list_len
;
memcpy
(
acx
->
mac_table
,
mc_list
,
mc_list_len
*
ETH_ALEN
);
...
...
@@ -308,6 +285,7 @@ int wl1271_acx_service_period_timeout(struct wl1271 *wl)
wl1271_debug
(
DEBUG_ACX
,
"acx service period timeout"
);
rx_timeout
->
role_id
=
wl
->
role_id
;
rx_timeout
->
ps_poll_timeout
=
cpu_to_le16
(
wl
->
conf
.
rx
.
ps_poll_timeout
);
rx_timeout
->
upsd_timeout
=
cpu_to_le16
(
wl
->
conf
.
rx
.
upsd_timeout
);
...
...
@@ -344,6 +322,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold)
goto
out
;
}
rts
->
role_id
=
wl
->
role_id
;
rts
->
threshold
=
cpu_to_le16
((
u16
)
rts_threshold
);
ret
=
wl1271_cmd_configure
(
wl
,
DOT11_RTS_THRESHOLD
,
rts
,
sizeof
(
*
rts
));
...
...
@@ -403,6 +382,7 @@ int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter)
goto
out
;
}
beacon_filter
->
role_id
=
wl
->
role_id
;
beacon_filter
->
enable
=
enable_filter
;
/*
...
...
@@ -439,6 +419,7 @@ int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
}
/* configure default beacon pass-through rules */
ie_table
->
role_id
=
wl
->
role_id
;
ie_table
->
num_ie
=
0
;
for
(
i
=
0
;
i
<
wl
->
conf
.
conn
.
bcn_filt_ie_count
;
i
++
)
{
struct
conf_bcn_filt_rule
*
r
=
&
(
wl
->
conf
.
conn
.
bcn_filt_ie
[
i
]);
...
...
@@ -500,6 +481,7 @@ int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable)
timeout
=
wl
->
conf
.
conn
.
bss_lose_timeout
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
synch_fail_thold
=
cpu_to_le32
(
threshold
);
acx
->
bss_lose_timeout
=
cpu_to_le32
(
timeout
);
...
...
@@ -546,43 +528,13 @@ int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
return
ret
;
}
int
wl1271_acx_sta_sg_cfg
(
struct
wl1271
*
wl
)
{
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 sta cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
/* BT-WLAN coext parameters */
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
)
int
wl12xx_acx_sg_cfg
(
struct
wl1271
*
wl
)
{
struct
acx_
ap_
bt_wlan_coex_param
*
param
;
struct
acx_bt_wlan_coex_param
*
param
;
struct
conf_sg_settings
*
c
=
&
wl
->
conf
.
sg
;
int
i
,
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx sg
ap
cfg"
);
wl1271_debug
(
DEBUG_ACX
,
"acx sg cfg"
);
param
=
kzalloc
(
sizeof
(
*
param
),
GFP_KERNEL
);
if
(
!
param
)
{
...
...
@@ -591,8 +543,8 @@ int wl1271_acx_ap_sg_cfg(struct wl1271 *wl)
}
/* BT-WLAN coext parameters */
for
(
i
=
0
;
i
<
CONF_SG_
AP_
PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
ap_
params
[
i
]);
for
(
i
=
0
;
i
<
CONF_SG_PARAMS_MAX
;
i
++
)
param
->
params
[
i
]
=
cpu_to_le32
(
c
->
params
[
i
]);
param
->
param_idx
=
CONF_SG_PARAMS_ALL
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SG_CFG
,
param
,
sizeof
(
*
param
));
...
...
@@ -647,6 +599,7 @@ int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
goto
out
;
}
bb
->
role_id
=
wl
->
role_id
;
bb
->
beacon_rx_timeout
=
cpu_to_le16
(
wl
->
conf
.
conn
.
beacon_rx_timeout
);
bb
->
broadcast_timeout
=
cpu_to_le16
(
wl
->
conf
.
conn
.
broadcast_timeout
);
bb
->
rx_broadcast_in_ps
=
wl
->
conf
.
conn
.
rx_broadcast_in_ps
;
...
...
@@ -676,6 +629,7 @@ int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
goto
out
;
}
acx_aid
->
role_id
=
wl
->
role_id
;
acx_aid
->
aid
=
cpu_to_le16
(
aid
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_AID
,
acx_aid
,
sizeof
(
*
acx_aid
));
...
...
@@ -731,6 +685,7 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
preamble
=
preamble
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_PREAMBLE_TYPE
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -758,6 +713,7 @@ int wl1271_acx_cts_protect(struct wl1271 *wl,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
ctsprotect
=
ctsprotect
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_CTS_PROTECTION
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -789,9 +745,8 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
int
wl1271_acx_sta_rate_policies
(
struct
wl1271
*
wl
)
{
struct
acx_
sta_
rate_policy
*
acx
;
struct
acx_rate_policy
*
acx
;
struct
conf_tx_rate_class
*
c
=
&
wl
->
conf
.
tx
.
sta_rc_conf
;
int
idx
=
0
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx rate policies"
);
...
...
@@ -803,25 +758,30 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
goto
out
;
}
wl1271_debug
(
DEBUG_ACX
,
"basic_rate: 0x%x, full_rate: 0x%x"
,
wl
->
basic_rate
,
wl
->
rate_set
);
/* configure one basic rate class */
idx
=
ACX_TX_BASIC_RATE
;
acx
->
rate_class
[
idx
].
enabled_rates
=
cpu_to_le32
(
wl
->
basic_rate
);
acx
->
rate_class
[
idx
].
short_retry_limit
=
c
->
short_retry_limit
;
acx
->
rate_class
[
idx
].
long_retry_limit
=
c
->
long_retry_limit
;
acx
->
rate_class
[
idx
].
aflags
=
c
->
aflags
;
acx
->
rate_policy_idx
=
cpu_to_le32
(
ACX_TX_BASIC_RATE
);
acx
->
rate_policy
.
enabled_rates
=
cpu_to_le32
(
wl
->
basic_rate
);
acx
->
rate_policy
.
short_retry_limit
=
c
->
short_retry_limit
;
acx
->
rate_policy
.
long_retry_limit
=
c
->
long_retry_limit
;
acx
->
rate_policy
.
aflags
=
c
->
aflags
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_RATE_POLICY
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"Setting of rate policies failed: %d"
,
ret
);
goto
out
;
}
/* configure one AP supported rate class */
idx
=
ACX_TX_AP_FULL_RATE
;
acx
->
rate_
class
[
idx
]
.
enabled_rates
=
cpu_to_le32
(
wl
->
rate_set
);
acx
->
rate_
class
[
idx
]
.
short_retry_limit
=
c
->
short_retry_limit
;
acx
->
rate_
class
[
idx
]
.
long_retry_limit
=
c
->
long_retry_limit
;
acx
->
rate_
class
[
idx
]
.
aflags
=
c
->
aflags
;
acx
->
rate_policy_idx
=
cpu_to_le32
(
ACX_TX_AP_FULL_RATE
)
;
acx
->
rate_
policy
.
enabled_rates
=
cpu_to_le32
(
wl
->
rate_set
);
acx
->
rate_
policy
.
short_retry_limit
=
c
->
short_retry_limit
;
acx
->
rate_
policy
.
long_retry_limit
=
c
->
long_retry_limit
;
acx
->
rate_
policy
.
aflags
=
c
->
aflags
;
acx
->
rate_class_cnt
=
cpu_to_le32
(
ACX_TX_RATE_POLICY_CNT
);
wl1271_debug
(
DEBUG_ACX
,
"basic_rate: 0x%x, full_rate: 0x%x"
,
acx
->
rate_class
[
ACX_TX_BASIC_RATE
].
enabled_rates
,
acx
->
rate_class
[
ACX_TX_AP_FULL_RATE
].
enabled_rates
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_RATE_POLICY
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
...
...
@@ -837,7 +797,7 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl)
int
wl1271_acx_ap_rate_policy
(
struct
wl1271
*
wl
,
struct
conf_tx_rate_class
*
c
,
u8
idx
)
{
struct
acx_
ap_
rate_policy
*
acx
;
struct
acx_rate_policy
*
acx
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx ap rate policy %d rates 0x%x"
,
...
...
@@ -883,6 +843,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
ac
=
ac
;
acx
->
cw_min
=
cw_min
;
acx
->
cw_max
=
cpu_to_le16
(
cw_max
);
...
...
@@ -916,6 +877,7 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
queue_id
=
queue_id
;
acx
->
channel_type
=
channel_type
;
acx
->
tsid
=
tsid
;
...
...
@@ -995,52 +957,9 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl)
return
ret
;
}
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"
);
mem_conf
=
kzalloc
(
sizeof
(
*
mem_conf
),
GFP_KERNEL
);
if
(
!
mem_conf
)
{
ret
=
-
ENOMEM
;
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 */
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
,
sizeof
(
*
mem_conf
));
if
(
ret
<
0
)
{
wl1271_warning
(
"wl1271 mem config failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
mem_conf
);
return
ret
;
}
int
wl1271_acx_sta_mem_cfg
(
struct
wl1271
*
wl
)
int
wl12xx_acx_mem_cfg
(
struct
wl1271
*
wl
)
{
struct
wl12
71_acx_sta
_config_memory
*
mem_conf
;
struct
wl12
xx_acx
_config_memory
*
mem_conf
;
struct
conf_memory_settings
*
mem
;
int
ret
;
...
...
@@ -1183,6 +1102,7 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
enable
=
enable
?
CONF_BET_MODE_ENABLE
:
CONF_BET_MODE_DISABLE
;
acx
->
max_consecutive
=
wl
->
conf
.
conn
.
bet_max_consecutive
;
...
...
@@ -1210,6 +1130,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, u8 enable, __be32 address)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
version
=
ACX_IPV4_VERSION
;
acx
->
enable
=
enable
;
...
...
@@ -1269,6 +1190,7 @@ int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
enabled
=
enable
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_KEEP_ALIVE_MODE
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -1295,6 +1217,7 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
period
=
cpu_to_le32
(
wl
->
conf
.
conn
.
keep_alive_interval
);
acx
->
index
=
index
;
acx
->
tpl_validation
=
tpl_valid
;
...
...
@@ -1328,6 +1251,7 @@ int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
wl
->
last_rssi_event
=
-
1
;
acx
->
role_id
=
wl
->
role_id
;
acx
->
pacing
=
cpu_to_le16
(
wl
->
conf
.
roam_trigger
.
trigger_pacing
);
acx
->
metric
=
WL1271_ACX_TRIG_METRIC_RSSI_BEACON
;
acx
->
type
=
WL1271_ACX_TRIG_TYPE_EDGE
;
...
...
@@ -1366,6 +1290,7 @@ int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
rssi_beacon
=
c
->
avg_weight_rssi_beacon
;
acx
->
rssi_data
=
c
->
avg_weight_rssi_data
;
acx
->
snr_beacon
=
c
->
avg_weight_snr_beacon
;
...
...
@@ -1384,14 +1309,15 @@ int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
int
wl1271_acx_set_ht_capabilities
(
struct
wl1271
*
wl
,
struct
ieee80211_sta_ht_cap
*
ht_cap
,
bool
allow_ht_operation
)
bool
allow_ht_operation
,
u8
hlid
)
{
struct
wl1271_acx_ht_capabilities
*
acx
;
u8
mac_address
[
ETH_ALEN
]
=
{
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
};
int
ret
=
0
;
u32
ht_capabilites
=
0
;
wl1271_debug
(
DEBUG_ACX
,
"acx ht capabilities setting"
);
wl1271_debug
(
DEBUG_ACX
,
"acx ht capabilities setting "
"sta supp: %d sta cap: %d"
,
ht_cap
->
ht_supported
,
ht_cap
->
cap
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
...
...
@@ -1399,26 +1325,22 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
goto
out
;
}
/* Allow HT Operation ? */
if
(
allow_ht_operation
)
{
ht_capabilites
=
WL1271_ACX_FW_CAP_HT_OPERATION
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_GRN_FLD
)
ht_capabilites
|=
WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_SGI_20
)
ht_capabilites
|=
WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS
;
if
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_LSIG_TXOP_PROT
)
ht_capabilites
|=
WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION
;
if
(
allow_ht_operation
&&
ht_cap
->
ht_supported
)
{
/* no need to translate capabilities - use the spec values */
ht_capabilites
=
ht_cap
->
cap
;
/*
* this bit is not employed by the spec but only by FW to
* indicate peer HT support
*/
ht_capabilites
|=
WL12XX_HT_CAP_HT_OPERATION
;
/* get data from A-MPDU parameters field */
acx
->
ampdu_max_length
=
ht_cap
->
ampdu_factor
;
acx
->
ampdu_min_spacing
=
ht_cap
->
ampdu_density
;
}
memcpy
(
acx
->
mac_address
,
mac_address
,
ETH_ALEN
)
;
acx
->
hlid
=
hlid
;
acx
->
ht_capabilites
=
cpu_to_le32
(
ht_capabilites
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_PEER_HT_CAP
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -1446,6 +1368,7 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
goto
out
;
}
acx
->
role_id
=
wl
->
role_id
;
acx
->
ht_protection
=
(
u8
)(
ht_operation_mode
&
IEEE80211_HT_OP_MODE_PROTECTION
);
acx
->
rifs_mode
=
0
;
...
...
@@ -1467,14 +1390,12 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
}
/* Configure BA session initiator/receiver parameters setting in the FW. */
int
wl1271_acx_set_ba_session
(
struct
wl1271
*
wl
,
enum
ieee80211_back_parties
direction
,
u8
tid_index
,
u8
policy
)
int
wl12xx_acx_set_ba_initiator_policy
(
struct
wl1271
*
wl
)
{
struct
wl1271_acx_ba_
session
_policy
*
acx
;
struct
wl1271_acx_ba_
initiator
_policy
*
acx
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx ba
session setting
"
);
wl1271_debug
(
DEBUG_ACX
,
"acx ba
initiator policy
"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
...
...
@@ -1482,33 +1403,18 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
goto
out
;
}
/* ANY role */
acx
->
role_id
=
0xff
;
acx
->
tid
=
tid_index
;
acx
->
enable
=
policy
;
acx
->
ba_direction
=
direction
;
switch
(
direction
)
{
case
WLAN_BACK_INITIATOR
:
acx
->
win_size
=
wl
->
conf
.
ht
.
tx_ba_win_size
;
acx
->
inactivity_timeout
=
wl
->
conf
.
ht
.
inactivity_timeout
;
break
;
case
WLAN_BACK_RECIPIENT
:
acx
->
win_size
=
RX_BA_WIN_SIZE
;
acx
->
inactivity_timeout
=
0
;
break
;
default:
wl1271_error
(
"Incorrect acx command id=%x
\n
"
,
direction
);
ret
=
-
EINVAL
;
goto
out
;
}
/* set for the current role */
acx
->
role_id
=
wl
->
role_id
;
acx
->
tid_bitmap
=
wl
->
conf
.
ht
.
tx_ba_tid_bitmap
;
acx
->
win_size
=
wl
->
conf
.
ht
.
tx_ba_win_size
;
acx
->
inactivity_timeout
=
wl
->
conf
.
ht
.
inactivity_timeout
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_BA_SESSION_
POLICY_CFG
,
ACX_BA_SESSION_
INIT_POLICY
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx ba
session setting
failed: %d"
,
ret
);
wl1271_warning
(
"acx ba
initiator policy
failed: %d"
,
ret
);
goto
out
;
}
...
...
@@ -1518,8 +1424,8 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
}
/* setup BA session receiver setting in the FW. */
int
wl12
71_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
)
int
wl12
xx_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
,
u8
peer_hlid
)
{
struct
wl1271_acx_ba_receiver_setup
*
acx
;
int
ret
;
...
...
@@ -1532,11 +1438,10 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
goto
out
;
}
/* Single link for now */
acx
->
link_id
=
1
;
acx
->
hlid
=
peer_hlid
;
acx
->
tid
=
tid_index
;
acx
->
enable
=
enable
;
acx
->
win_size
=
0
;
acx
->
win_size
=
wl
->
conf
.
ht
.
rx_ba_win_size
;
acx
->
ssn
=
ssn
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_BA_SESSION_RX_SETUP
,
acx
,
...
...
@@ -1606,6 +1511,7 @@ int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable)
if
(
!
(
conf_queues
&
BIT
(
i
)))
continue
;
rx_streaming
->
role_id
=
wl
->
role_id
;
rx_streaming
->
tid
=
i
;
rx_streaming
->
enable
=
enable_queues
&
BIT
(
i
);
rx_streaming
->
period
=
wl
->
conf
.
rx_streaming
.
interval
;
...
...
@@ -1635,6 +1541,7 @@ int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl)
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
role_id
=
wl
->
role_id
;
acx
->
max_tx_retry
=
cpu_to_le16
(
wl
->
conf
.
tx
.
max_tx_retries
);
ret
=
wl1271_cmd_configure
(
wl
,
ACX_MAX_TX_FAILURE
,
acx
,
sizeof
(
*
acx
));
...
...
@@ -1703,31 +1610,6 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
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
;
...
...
@@ -1767,3 +1649,45 @@ int wl1271_acx_fm_coex(struct wl1271 *wl)
kfree
(
acx
);
return
ret
;
}
int
wl12xx_acx_set_rate_mgmt_params
(
struct
wl1271
*
wl
)
{
struct
wl12xx_acx_set_rate_mgmt_params
*
acx
=
NULL
;
struct
conf_rate_policy_settings
*
conf
=
&
wl
->
conf
.
rate
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx set rate mgmt params"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
return
-
ENOMEM
;
acx
->
index
=
ACX_RATE_MGMT_ALL_PARAMS
;
acx
->
rate_retry_score
=
cpu_to_le16
(
conf
->
rate_retry_score
);
acx
->
per_add
=
cpu_to_le16
(
conf
->
per_add
);
acx
->
per_th1
=
cpu_to_le16
(
conf
->
per_th1
);
acx
->
per_th2
=
cpu_to_le16
(
conf
->
per_th2
);
acx
->
max_per
=
cpu_to_le16
(
conf
->
max_per
);
acx
->
inverse_curiosity_factor
=
conf
->
inverse_curiosity_factor
;
acx
->
tx_fail_low_th
=
conf
->
tx_fail_low_th
;
acx
->
tx_fail_high_th
=
conf
->
tx_fail_high_th
;
acx
->
per_alpha_shift
=
conf
->
per_alpha_shift
;
acx
->
per_add_shift
=
conf
->
per_add_shift
;
acx
->
per_beta1_shift
=
conf
->
per_beta1_shift
;
acx
->
per_beta2_shift
=
conf
->
per_beta2_shift
;
acx
->
rate_check_up
=
conf
->
rate_check_up
;
acx
->
rate_check_down
=
conf
->
rate_check_down
;
memcpy
(
acx
->
rate_retry_policy
,
conf
->
rate_retry_policy
,
sizeof
(
acx
->
rate_retry_policy
));
ret
=
wl1271_cmd_configure
(
wl
,
ACX_SET_RATE_MGMT_PARAMS
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx set rate mgmt params failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
drivers/net/wireless/wl12xx/acx.h
浏览文件 @
e0a8c583
...
...
@@ -101,6 +101,17 @@ struct acx_error_counter {
__le32
seq_num_miss
;
}
__packed
;
enum
wl12xx_role
{
WL1271_ROLE_STA
=
0
,
WL1271_ROLE_IBSS
,
WL1271_ROLE_AP
,
WL1271_ROLE_DEVICE
,
WL1271_ROLE_P2P_CL
,
WL1271_ROLE_P2P_GO
,
WL12XX_INVALID_ROLE_TYPE
=
0xff
};
enum
wl1271_psm_mode
{
/* Active mode */
WL1271_PSM_CAM
=
0
,
...
...
@@ -160,94 +171,6 @@ struct acx_rx_msdu_lifetime {
__le32
lifetime
;
}
__packed
;
/*
* RX Config Options Table
* Bit Definition
* === ==========
* 31:14 Reserved
* 13 Copy RX Status - when set, write three receive status words
* to top of rx'd MPDUs.
* When cleared, do not write three status words (added rev 1.5)
* 12 Reserved
* 11 RX Complete upon FCS error - when set, give rx complete
* interrupt for FCS errors, after the rx filtering, e.g. unicast
* frames not to us with FCS error will not generate an interrupt.
* 10 SSID Filter Enable - When set, the WiLink discards all beacon,
* probe request, and probe response frames with an SSID that does
* not match the SSID specified by the host in the START/JOIN
* command.
* When clear, the WiLink receives frames with any SSID.
* 9 Broadcast Filter Enable - When set, the WiLink discards all
* broadcast frames. When clear, the WiLink receives all received
* broadcast frames.
* 8:6 Reserved
* 5 BSSID Filter Enable - When set, the WiLink discards any frames
* with a BSSID that does not match the BSSID specified by the
* host.
* When clear, the WiLink receives frames from any BSSID.
* 4 MAC Addr Filter - When set, the WiLink discards any frames
* with a destination address that does not match the MAC address
* of the adaptor.
* When clear, the WiLink receives frames destined to any MAC
* address.
* 3 Promiscuous - When set, the WiLink receives all valid frames
* (i.e., all frames that pass the FCS check).
* When clear, only frames that pass the other filters specified
* are received.
* 2 FCS - When set, the WiLink includes the FCS with the received
* frame.
* When cleared, the FCS is discarded.
* 1 PLCP header - When set, write all data from baseband to frame
* buffer including PHY header.
* 0 Reserved - Always equal to 0.
*
* RX Filter Options Table
* Bit Definition
* === ==========
* 31:12 Reserved - Always equal to 0.
* 11 Association - When set, the WiLink receives all association
* related frames (association request/response, reassocation
* request/response, and disassociation). When clear, these frames
* are discarded.
* 10 Auth/De auth - When set, the WiLink receives all authentication
* and de-authentication frames. When clear, these frames are
* discarded.
* 9 Beacon - When set, the WiLink receives all beacon frames.
* When clear, these frames are discarded.
* 8 Contention Free - When set, the WiLink receives all contention
* free frames.
* When clear, these frames are discarded.
* 7 Control - When set, the WiLink receives all control frames.
* When clear, these frames are discarded.
* 6 Data - When set, the WiLink receives all data frames.
* When clear, these frames are discarded.
* 5 FCS Error - When set, the WiLink receives frames that have FCS
* errors.
* When clear, these frames are discarded.
* 4 Management - When set, the WiLink receives all management
* frames.
* When clear, these frames are discarded.
* 3 Probe Request - When set, the WiLink receives all probe request
* frames.
* When clear, these frames are discarded.
* 2 Probe Response - When set, the WiLink receives all probe
* response frames.
* When clear, these frames are discarded.
* 1 RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
* frames.
* When clear, these frames are discarded.
* 0 Rsvd Type/Sub Type - When set, the WiLink receives all frames
* that have reserved frame types and sub types as defined by the
* 802.11 specification.
* When clear, these frames are discarded.
*/
struct
acx_rx_config
{
struct
acx_header
header
;
__le32
config_options
;
__le32
filter_options
;
}
__packed
;
struct
acx_packet_detection
{
struct
acx_header
header
;
...
...
@@ -267,9 +190,10 @@ enum acx_slot_type {
struct
acx_slot
{
struct
acx_header
header
;
u8
role_id
;
u8
wone_index
;
/* Reserved */
u8
slot_time
;
u8
reserved
[
6
];
u8
reserved
[
5
];
}
__packed
;
...
...
@@ -279,29 +203,35 @@ struct acx_slot {
struct
acx_dot11_grp_addr_tbl
{
struct
acx_header
header
;
u8
role_id
;
u8
enabled
;
u8
num_groups
;
u8
pad
[
2
];
u8
pad
[
1
];
u8
mac_table
[
ADDRESS_GROUP_MAX_LEN
];
}
__packed
;
struct
acx_rx_timeout
{
struct
acx_header
header
;
u8
role_id
;
u8
reserved
;
__le16
ps_poll_timeout
;
__le16
upsd_timeout
;
u8
padding
[
2
];
}
__packed
;
struct
acx_rts_threshold
{
struct
acx_header
header
;
u8
role_id
;
u8
reserved
;
__le16
threshold
;
u8
pad
[
2
];
}
__packed
;
struct
acx_beacon_filter_option
{
struct
acx_header
header
;
u8
role_id
;
u8
enable
;
/*
* The number of beacons without the unicast TIM
...
...
@@ -311,7 +241,7 @@ struct acx_beacon_filter_option {
* without the unicast TIM bit set are dropped.
*/
u8
max_num_beacons
;
u8
pad
[
2
];
u8
pad
[
1
];
}
__packed
;
/*
...
...
@@ -350,14 +280,17 @@ struct acx_beacon_filter_option {
struct
acx_beacon_filter_ie_table
{
struct
acx_header
header
;
u8
role_id
;
u8
num_ie
;
u8
pad
[
3
];
u8
pad
[
2
];
u8
table
[
BEACON_FILTER_TABLE_MAX_SIZE
];
}
__packed
;
struct
acx_conn_monit_params
{
struct
acx_header
header
;
u8
role_id
;
u8
padding
[
3
];
__le32
synch_fail_thold
;
/* number of beacons missed */
__le32
bss_lose_timeout
;
/* number of TU's from synch fail */
}
__packed
;
...
...
@@ -369,23 +302,14 @@ struct acx_bt_wlan_coex {
u8
pad
[
3
];
}
__packed
;
struct
acx_sta_bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_STA_PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_ap_bt_wlan_coex_param
{
struct
acx_bt_wlan_coex_param
{
struct
acx_header
header
;
__le32
params
[
CONF_SG_
AP_
PARAMS_MAX
];
__le32
params
[
CONF_SG_PARAMS_MAX
];
u8
param_idx
;
u8
padding
[
3
];
}
__packed
;
struct
acx_dco_itrim_params
{
struct
acx_header
header
;
...
...
@@ -406,15 +330,16 @@ struct acx_energy_detection {
struct
acx_beacon_broadcast
{
struct
acx_header
header
;
__le16
beacon_rx_timeout
;
__le16
broadcast_timeout
;
u8
role_id
;
/* Enables receiving of broadcast packets in PS mode */
u8
rx_broadcast_in_ps
;
__le16
beacon_rx_timeout
;
__le16
broadcast_timeout
;
/* Consecutive PS Poll failures before updating the host */
u8
ps_poll_threshold
;
u8
pad
[
2
];
u8
pad
[
1
];
}
__packed
;
struct
acx_event_mask
{
...
...
@@ -424,35 +349,6 @@ struct acx_event_mask {
__le32
high_event_mask
;
/* Unused */
}
__packed
;
#define CFG_RX_FCS BIT(2)
#define CFG_RX_ALL_GOOD BIT(3)
#define CFG_UNI_FILTER_EN BIT(4)
#define CFG_BSSID_FILTER_EN BIT(5)
#define CFG_MC_FILTER_EN BIT(6)
#define CFG_MC_ADDR0_EN BIT(7)
#define CFG_MC_ADDR1_EN BIT(8)
#define CFG_BC_REJECT_EN BIT(9)
#define CFG_SSID_FILTER_EN BIT(10)
#define CFG_RX_INT_FCS_ERROR BIT(11)
#define CFG_RX_INT_ENCRYPTED BIT(12)
#define CFG_RX_WR_RX_STATUS BIT(13)
#define CFG_RX_FILTER_NULTI BIT(14)
#define CFG_RX_RESERVE BIT(15)
#define CFG_RX_TIMESTAMP_TSF BIT(16)
#define CFG_RX_RSV_EN BIT(0)
#define CFG_RX_RCTS_ACK BIT(1)
#define CFG_RX_PRSP_EN BIT(2)
#define CFG_RX_PREQ_EN BIT(3)
#define CFG_RX_MGMT_EN BIT(4)
#define CFG_RX_FCS_ERROR BIT(5)
#define CFG_RX_DATA_EN BIT(6)
#define CFG_RX_CTL_EN BIT(7)
#define CFG_RX_CF_EN BIT(8)
#define CFG_RX_BCN_EN BIT(9)
#define CFG_RX_AUTH_EN BIT(10)
#define CFG_RX_ASSOC_EN BIT(11)
#define SCAN_PASSIVE BIT(0)
#define SCAN_5GHZ_BAND BIT(1)
#define SCAN_TRIGGERED BIT(2)
...
...
@@ -465,6 +361,8 @@ struct acx_event_mask {
struct
acx_feature_config
{
struct
acx_header
header
;
u8
role_id
;
u8
padding
[
3
];
__le32
options
;
__le32
data_flow_options
;
}
__packed
;
...
...
@@ -472,16 +370,18 @@ struct acx_feature_config {
struct
acx_current_tx_power
{
struct
acx_header
header
;
u8
role_id
;
u8
current_tx_power
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
struct
acx_wake_up_condition
{
struct
acx_header
header
;
u8
role_id
;
u8
wake_up_event
;
/* Only one bit can be set */
u8
listen_interval
;
u8
pad
[
2
];
u8
pad
[
1
];
}
__packed
;
struct
acx_aid
{
...
...
@@ -490,8 +390,9 @@ struct acx_aid {
/*
* To be set when associated with an AP.
*/
u8
role_id
;
u8
reserved
;
__le16
aid
;
u8
pad
[
2
];
}
__packed
;
enum
acx_preamble_type
{
...
...
@@ -506,8 +407,9 @@ struct acx_preamble {
* When set, the WiLink transmits the frames with a short preamble and
* when cleared, the WiLink transmits the frames with a long preamble.
*/
u8
role_id
;
u8
preamble
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
enum
acx_ctsprotect_type
{
...
...
@@ -517,8 +419,9 @@ enum acx_ctsprotect_type {
struct
acx_ctsprotect
{
struct
acx_header
header
;
u8
role_id
;
u8
ctsprotect
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
struct
acx_tx_statistics
{
...
...
@@ -753,18 +656,9 @@ struct acx_rate_class {
#define ACX_TX_BASIC_RATE 0
#define ACX_TX_AP_FULL_RATE 1
#define ACX_TX_RATE_POLICY_CNT 2
struct
acx_sta_rate_policy
{
struct
acx_header
header
;
__le32
rate_class_cnt
;
struct
acx_rate_class
rate_class
[
CONF_TX_MAX_RATE_CLASSES
];
}
__packed
;
#define ACX_TX_AP_MODE_MGMT_RATE 4
#define ACX_TX_AP_MODE_BCST_RATE 5
struct
acx_
ap_
rate_policy
{
struct
acx_rate_policy
{
struct
acx_header
header
;
__le32
rate_policy_idx
;
...
...
@@ -773,22 +667,23 @@ struct acx_ap_rate_policy {
struct
acx_ac_cfg
{
struct
acx_header
header
;
u8
role_id
;
u8
ac
;
u8
aifsn
;
u8
cw_min
;
__le16
cw_max
;
u8
aifsn
;
u8
reserved
;
__le16
tx_op_limit
;
}
__packed
;
struct
acx_tid_config
{
struct
acx_header
header
;
u8
role_id
;
u8
queue_id
;
u8
channel_type
;
u8
tsid
;
u8
ps_scheme
;
u8
ack_policy
;
u8
padding
[
3
];
u8
padding
[
2
];
__le32
apsd_conf
[
2
];
}
__packed
;
...
...
@@ -804,19 +699,7 @@ struct acx_tx_config_options {
__le16
tx_compl_threshold
;
/* number of packets */
}
__packed
;
#define ACX_TX_DESCRIPTORS 32
struct
wl1271_acx_ap_config_memory
{
struct
acx_header
header
;
u8
rx_mem_block_num
;
u8
tx_min_mem_block_num
;
u8
num_stations
;
u8
num_ssid_profiles
;
__le32
total_tx_descriptors
;
}
__packed
;
struct
wl1271_acx_sta_config_memory
{
struct
wl12xx_acx_config_memory
{
struct
acx_header
header
;
u8
rx_mem_block_num
;
...
...
@@ -890,9 +773,10 @@ struct wl1271_acx_rx_config_opt {
struct
wl1271_acx_bet_enable
{
struct
acx_header
header
;
u8
role_id
;
u8
enable
;
u8
max_consecutive
;
u8
padding
[
2
];
u8
padding
[
1
];
}
__packed
;
#define ACX_IPV4_VERSION 4
...
...
@@ -905,9 +789,10 @@ struct wl1271_acx_bet_enable {
struct
wl1271_acx_arp_filter
{
struct
acx_header
header
;
u8
role_id
;
u8
version
;
/* ACX_IPV4_VERSION, ACX_IPV6_VERSION */
u8
enable
;
/* bitmap of enabled ARP filtering features */
u8
padding
[
2
];
u8
padding
[
1
];
u8
address
[
16
];
/* The configured device IP address - all ARP
requests directed to this IP address will pass
through. For IPv4, the first four bytes are
...
...
@@ -925,8 +810,9 @@ struct wl1271_acx_pm_config {
struct
wl1271_acx_keep_alive_mode
{
struct
acx_header
header
;
u8
role_id
;
u8
enabled
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
enum
{
...
...
@@ -942,11 +828,11 @@ enum {
struct
wl1271_acx_keep_alive_config
{
struct
acx_header
header
;
__le32
perio
d
;
u8
role_i
d
;
u8
index
;
u8
tpl_validation
;
u8
trigger
;
u8
padding
;
__le32
period
;
}
__packed
;
#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
...
...
@@ -990,26 +876,33 @@ enum {
struct
wl1271_acx_rssi_snr_trigger
{
struct
acx_header
header
;
__le16
threshold
;
__le16
pacing
;
/* 0 - 60000 ms */
u8
role_id
;
u8
metric
;
u8
type
;
u8
dir
;
__le16
threshold
;
__le16
pacing
;
/* 0 - 60000 ms */
u8
hysteresis
;
u8
index
;
u8
enable
;
u8
padding
[
2
];
u8
padding
[
1
];
};
struct
wl1271_acx_rssi_snr_avg_weights
{
struct
acx_header
header
;
u8
role_id
;
u8
padding
[
3
];
u8
rssi_beacon
;
u8
rssi_data
;
u8
snr_beacon
;
u8
snr_data
;
};
/* special capability bit (not employed by the 802.11n spec) */
#define WL12XX_HT_CAP_HT_OPERATION BIT(16)
/*
* ACX_PEER_HT_CAP
* Configure HT capabilities - declare the capabilities of the peer
...
...
@@ -1018,28 +911,11 @@ struct wl1271_acx_rssi_snr_avg_weights {
struct
wl1271_acx_ht_capabilities
{
struct
acx_header
header
;
/*
* bit 0 - Allow HT Operation
* bit 1 - Allow Greenfield format in TX
* bit 2 - Allow Short GI in TX
* bit 3 - Allow L-SIG TXOP Protection in TX
* bit 4 - Allow HT Control fields in TX.
* Note, driver will still leave space for HT control in packets
* regardless of the value of this field. FW will be responsible
* to drop the HT field from any frame when this Bit set to 0.
* bit 5 - Allow RD initiation in TXOP. FW is allowed to initate RD.
* Exact policy setting for this feature is TBD.
* Note, this bit can only be set to 1 if bit 3 is set to 1.
*/
/* bitmask of capability bits supported by the peer */
__le32
ht_capabilites
;
/*
* Indicates to which peer these capabilities apply.
* For infrastructure use ff:ff:ff:ff:ff:ff that indicates relevance
* for all peers.
* Only valid for IBSS/DLS operation.
*/
u8
mac_address
[
ETH_ALEN
];
/* Indicates to which link these capabilities apply. */
u8
hlid
;
/*
* This the maximum A-MPDU length supported by the AP. The FW may not
...
...
@@ -1049,16 +925,9 @@ struct wl1271_acx_ht_capabilities {
/* This is the minimal spacing required when sending A-MPDUs to the AP*/
u8
ampdu_min_spacing
;
}
__packed
;
/* HT Capabilites Fw Bit Mask Mapping */
#define WL1271_ACX_FW_CAP_HT_OPERATION BIT(0)
#define WL1271_ACX_FW_CAP_GREENFIELD_FRAME_FORMAT BIT(1)
#define WL1271_ACX_FW_CAP_SHORT_GI_FOR_20MHZ_PACKETS BIT(2)
#define WL1271_ACX_FW_CAP_LSIG_TXOP_PROTECTION BIT(3)
#define WL1271_ACX_FW_CAP_HT_CONTROL_FIELDS BIT(4)
#define WL1271_ACX_FW_CAP_RD_INITIATION BIT(5)
u8
padding
;
}
__packed
;
/*
* ACX_HT_BSS_OPERATION
...
...
@@ -1067,6 +936,8 @@ struct wl1271_acx_ht_capabilities {
struct
wl1271_acx_ht_information
{
struct
acx_header
header
;
u8
role_id
;
/* Values: 0 - RIFS not allowed, 1 - RIFS allowed */
u8
rifs_mode
;
...
...
@@ -1088,60 +959,51 @@ struct wl1271_acx_ht_information {
*/
u8
dual_cts_protection
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
#define RX_BA_
WIN_SIZE 8
#define RX_BA_
MAX_SESSIONS 2
struct
wl1271_acx_ba_
session
_policy
{
struct
wl1271_acx_ba_
initiator
_policy
{
struct
acx_header
header
;
/*
* Specifies role Id, Range 0-7, 0xFF means ANY role.
* Future use. For now this field is irrelevant
*/
/* Specifies role Id, Range 0-7, 0xFF means ANY role. */
u8
role_id
;
/*
*
Specifies Link Id, Range 0-31, 0xFF means ANY Link Id.
*
Not applicable if Role Id is set to ANY
.
*
Per TID setting for allowing TX BA. Set a bit to 1 to allow
*
TX BA sessions for the corresponding TID
.
*/
u8
link_id
;
u8
tid
;
u8
enable
;
u8
tid_bitmap
;
/* Windows size in number of packets */
u
16
win_size
;
u
8
win_size
;
/*
* As initiator inactivity timeout in time units(TU) of 1024us.
* As receiver reserved
*/
u16
inactivity_timeout
;
u8
padding1
[
1
];
/*
Initiator = 1/Receiver = 0
*/
u
8
ba_direction
;
/*
As initiator inactivity timeout in time units(TU) of 1024us
*/
u
16
inactivity_timeout
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
struct
wl1271_acx_ba_receiver_setup
{
struct
acx_header
header
;
/* Specifies
Link Id, Range 0-31, 0xFF means ANY Link Id
*/
u8
link_
id
;
/* Specifies
link id, range 0-31
*/
u8
hl
id
;
u8
tid
;
u8
enable
;
u8
padding
[
1
];
/* Windows size in number of packets */
u
16
win_size
;
u
8
win_size
;
/* BA session starting sequence number. RANGE 0-FFF */
u16
ssn
;
u8
padding
[
2
];
}
__packed
;
struct
wl1271_acx_fw_tsf_information
{
...
...
@@ -1158,6 +1020,7 @@ struct wl1271_acx_fw_tsf_information {
struct
wl1271_acx_ps_rx_streaming
{
struct
acx_header
header
;
u8
role_id
;
u8
tid
;
u8
enable
;
...
...
@@ -1166,17 +1029,20 @@ struct wl1271_acx_ps_rx_streaming {
/* timeout before first trigger (0-200 msec) */
u8
timeout
;
u8
padding
[
3
];
}
__packed
;
struct
wl1271_acx_ap_max_tx_retry
{
struct
acx_header
header
;
u8
role_id
;
u8
padding_1
;
/*
* the number of frames transmission failures before
* issuing the aging event.
*/
__le16
max_tx_retry
;
u8
padding_1
[
2
];
}
__packed
;
struct
wl1271_acx_config_ps
{
...
...
@@ -1195,13 +1061,6 @@ 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.
...
...
@@ -1261,6 +1120,30 @@ struct wl1271_acx_fm_coex {
u8
swallow_clk_diff
;
}
__packed
;
#define ACX_RATE_MGMT_ALL_PARAMS 0xff
struct
wl12xx_acx_set_rate_mgmt_params
{
struct
acx_header
header
;
u8
index
;
/* 0xff to configure all params */
u8
padding1
;
__le16
rate_retry_score
;
__le16
per_add
;
__le16
per_th1
;
__le16
per_th2
;
__le16
max_per
;
u8
inverse_curiosity_factor
;
u8
tx_fail_low_th
;
u8
tx_fail_high_th
;
u8
per_alpha_shift
;
u8
per_add_shift
;
u8
per_beta1_shift
;
u8
per_beta2_shift
;
u8
rate_check_up
;
u8
rate_check_down
;
u8
rate_retry_policy
[
ACX_RATE_MGMT_NUM_OF_RATES
];
u8
padding2
[
2
];
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
...
...
@@ -1268,10 +1151,7 @@ enum {
ACX_AC_CFG
=
0x0007
,
ACX_MEM_MAP
=
0x0008
,
ACX_AID
=
0x000A
,
/* ACX_FW_REV is missing in the ref driver, but seems to work */
ACX_FW_REV
=
0x000D
,
ACX_MEDIUM_USAGE
=
0x000F
,
ACX_RX_CFG
=
0x0010
,
ACX_TX_QUEUE_CFG
=
0x0011
,
/* FIXME: only used by wl1251 */
ACX_STATISTICS
=
0x0013
,
/* Debug API */
ACX_PWR_CONSUMPTION_STATISTICS
=
0x0014
,
...
...
@@ -1279,7 +1159,6 @@ 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
,
...
...
@@ -1287,7 +1166,6 @@ enum {
ACX_CCA_THRESHOLD
=
0x0025
,
ACX_EVENT_MBOX_MASK
=
0x0026
,
ACX_CONN_MONIT_PARAMS
=
0x002D
,
ACX_CONS_TX_FAILURE
=
0x002F
,
ACX_BCN_DTIM_OPTIONS
=
0x0031
,
ACX_SG_ENABLE
=
0x0032
,
ACX_SG_CFG
=
0x0033
,
...
...
@@ -1314,11 +1192,14 @@ enum {
ACX_RSSI_SNR_WEIGHTS
=
0x0052
,
ACX_KEEP_ALIVE_MODE
=
0x0053
,
ACX_SET_KEEP_ALIVE_CONFIG
=
0x0054
,
ACX_BA_SESSION_
POLICY_CFG
=
0x0055
,
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
,
...
...
@@ -1342,7 +1223,6 @@ int wl1271_acx_feature_cfg(struct wl1271 *wl);
int
wl1271_acx_mem_map
(
struct
wl1271
*
wl
,
struct
acx_header
*
mem_map
,
size_t
len
);
int
wl1271_acx_rx_msdu_life_time
(
struct
wl1271
*
wl
);
int
wl1271_acx_rx_config
(
struct
wl1271
*
wl
,
u32
config
,
u32
filter
);
int
wl1271_acx_pd_threshold
(
struct
wl1271
*
wl
);
int
wl1271_acx_slot
(
struct
wl1271
*
wl
,
enum
acx_slot_type
slot_time
);
int
wl1271_acx_group_address_tbl
(
struct
wl1271
*
wl
,
bool
enable
,
...
...
@@ -1354,8 +1234,7 @@ 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_sta_sg_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_ap_sg_cfg
(
struct
wl1271
*
wl
);
int
wl12xx_acx_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
);
...
...
@@ -1374,8 +1253,7 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
u32
apsd_conf0
,
u32
apsd_conf1
);
int
wl1271_acx_frag_threshold
(
struct
wl1271
*
wl
,
u32
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
);
int
wl12xx_acx_mem_cfg
(
struct
wl1271
*
wl
);
int
wl1271_acx_init_mem_config
(
struct
wl1271
*
wl
);
int
wl1271_acx_host_if_cfg_bitmap
(
struct
wl1271
*
wl
,
u32
host_cfg_bitmap
);
int
wl1271_acx_init_rx_interrupt
(
struct
wl1271
*
wl
);
...
...
@@ -1390,20 +1268,18 @@ int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
int
wl1271_acx_rssi_snr_avg_weights
(
struct
wl1271
*
wl
);
int
wl1271_acx_set_ht_capabilities
(
struct
wl1271
*
wl
,
struct
ieee80211_sta_ht_cap
*
ht_cap
,
bool
allow_ht_operation
);
bool
allow_ht_operation
,
u8
hlid
);
int
wl1271_acx_set_ht_information
(
struct
wl1271
*
wl
,
u16
ht_operation_mode
);
int
wl1271_acx_set_ba_session
(
struct
wl1271
*
wl
,
enum
ieee80211_back_parties
direction
,
u8
tid_index
,
u8
policy
);
int
wl1271_acx_set_ba_receiver_session
(
struct
wl1271
*
wl
,
u8
tid_index
,
u16
ssn
,
bool
enable
);
int
wl12xx_acx_set_ba_initiator_policy
(
struct
wl1271
*
wl
);
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
wl1271_acx_ps_rx_streaming
(
struct
wl1271
*
wl
,
bool
enable
);
int
wl1271_acx_ap_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
);
int
wl12xx_acx_set_rate_mgmt_params
(
struct
wl1271
*
wl
);
#endif
/* __WL1271_ACX_H__ */
drivers/net/wireless/wl12xx/boot.c
浏览文件 @
e0a8c583
...
...
@@ -107,16 +107,6 @@ static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl)
unsigned
int
quirks
=
0
;
unsigned
int
*
fw_ver
=
wl
->
chip
.
fw_ver
;
/* Only for wl127x */
if
((
fw_ver
[
FW_VER_CHIP
]
==
FW_VER_CHIP_WL127X
)
&&
/* Check STA version */
(((
fw_ver
[
FW_VER_IF_TYPE
]
==
FW_VER_IF_TYPE_STA
)
&&
(
fw_ver
[
FW_VER_MINOR
]
<
FW_VER_MINOR_1_SPARE_STA_MIN
))
||
/* Check AP version */
((
fw_ver
[
FW_VER_IF_TYPE
]
==
FW_VER_IF_TYPE_AP
)
&&
(
fw_ver
[
FW_VER_MINOR
]
<
FW_VER_MINOR_1_SPARE_AP_MIN
))))
quirks
|=
WL12XX_QUIRK_USE_2_SPARE_BLOCKS
;
/* Only new station firmwares support routing fw logs to the host */
if
((
fw_ver
[
FW_VER_IF_TYPE
]
==
FW_VER_IF_TYPE_STA
)
&&
(
fw_ver
[
FW_VER_MINOR
]
<
FW_VER_MINOR_FWLOG_STA_MIN
))
...
...
@@ -504,21 +494,18 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
wl
->
event_mask
=
BSS_LOSE_EVENT_ID
|
SCAN_COMPLETE_EVENT_ID
|
PS_REPORT_EVENT_ID
|
JOIN_EVENT_COMPLETE_ID
|
DISCONNECT_EVENT_COMPLETE_ID
|
RSSI_SNR_TRIGGER_0_EVENT_ID
|
PSPOLL_DELIVERY_FAILURE_EVENT_ID
|
SOFT_GEMINI_SENSE_EVENT_ID
|
PERIODIC_SCAN_REPORT_EVENT_ID
|
PERIODIC_SCAN_COMPLETE_EVENT_ID
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
event_mask
|=
STA_REMOVE_COMPLETE_EVENT_ID
|
INACTIVE_STA_EVENT_ID
|
MAX_TX_RETRY_EVENT_ID
;
else
wl
->
event_mask
|=
DUMMY_PACKET_EVENT_ID
|
BA_SESSION_RX_CONSTRAINT_EVENT_ID
;
PERIODIC_SCAN_COMPLETE_EVENT_ID
|
DUMMY_PACKET_EVENT_ID
|
PEER_REMOVE_COMPLETE_EVENT_ID
|
BA_SESSION_RX_CONSTRAINT_EVENT_ID
|
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID
|
INACTIVE_STA_EVENT_ID
|
MAX_TX_RETRY_EVENT_ID
;
ret
=
wl1271_event_unmask
(
wl
);
if
(
ret
<
0
)
{
...
...
@@ -549,13 +536,13 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
{
u32
fuse
;
fuse
=
wl1271_top_reg_read
(
wl
,
REG_FUSE_DATA_2_1
);
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
;
if
(((
wl
->
hw_pg_ver
&
PG_MAJOR_VER_MASK
)
>>
PG_MAJOR_VER_OFFSET
)
<
3
)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
}
static
int
wl128x_switch_tcxo_to_fref
(
struct
wl1271
*
wl
)
...
...
@@ -696,7 +683,8 @@ static int wl127x_boot_clk(struct wl1271 *wl)
u32
pause
;
u32
clk
;
wl1271_boot_hw_version
(
wl
);
if
(((
wl
->
hw_pg_ver
&
PG_MAJOR_VER_MASK
)
>>
PG_MAJOR_VER_OFFSET
)
<
3
)
wl
->
quirks
|=
WL12XX_QUIRK_END_OF_TRANSACTION
;
if
(
wl
->
ref_clock
==
CONF_REF_CLK_19_2_E
||
wl
->
ref_clock
==
CONF_REF_CLK_38_4_E
||
...
...
@@ -750,6 +738,8 @@ 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
)
...
...
@@ -852,9 +842,6 @@ int wl1271_boot(struct wl1271 *wl)
/* Enable firmware interrupts now */
wl1271_boot_enable_interrupts
(
wl
);
/* set the wl1271 default filters */
wl1271_set_default_filters
(
wl
);
wl1271_event_mbox_config
(
wl
);
out:
...
...
drivers/net/wireless/wl12xx/boot.h
浏览文件 @
e0a8c583
...
...
@@ -55,7 +55,8 @@ struct wl1271_static_data {
#define OCP_REG_CLK_POLARITY 0x0cb2
#define OCP_REG_CLK_PULL 0x0cb4
#define REG_FUSE_DATA_2_1 0x050a
#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
...
...
drivers/net/wireless/wl12xx/cmd.c
浏览文件 @
e0a8c583
...
...
@@ -363,63 +363,470 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
return
0
;
}
int
wl12
71_cmd_join
(
struct
wl1271
*
wl
,
u8
bss_type
)
int
wl12
xx_cmd_role_enable
(
struct
wl1271
*
wl
,
u8
role_type
,
u8
*
role_id
)
{
struct
wl1271_cmd_join
*
join
;
int
ret
,
i
;
u8
*
bssid
;
struct
wl12xx_cmd_role_enable
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd role enable"
);
join
=
kzalloc
(
sizeof
(
*
join
),
GFP_KERNEL
);
if
(
!
join
)
{
if
(
WARN_ON
(
*
role_id
!=
WL12XX_INVALID_ROLE_ID
))
return
-
EBUSY
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd join"
);
/* get role id */
cmd
->
role_id
=
find_first_zero_bit
(
wl
->
roles_map
,
WL12XX_MAX_ROLES
);
if
(
cmd
->
role_id
>=
WL12XX_MAX_ROLES
)
{
ret
=
-
EBUSY
;
goto
out_free
;
}
memcpy
(
cmd
->
mac_address
,
wl
->
mac_addr
,
ETH_ALEN
);
cmd
->
role_type
=
role_type
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_ENABLE
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role enable"
);
goto
out_free
;
}
__set_bit
(
cmd
->
role_id
,
wl
->
roles_map
);
*
role_id
=
cmd
->
role_id
;
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_disable
(
struct
wl1271
*
wl
,
u8
*
role_id
)
{
struct
wl12xx_cmd_role_disable
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd role disable"
);
if
(
WARN_ON
(
*
role_id
==
WL12XX_INVALID_ROLE_ID
))
return
-
ENOENT
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
role_id
=
*
role_id
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_DISABLE
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role disable"
);
goto
out_free
;
}
__clear_bit
(
*
role_id
,
wl
->
roles_map
);
*
role_id
=
WL12XX_INVALID_ROLE_ID
;
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
static
int
wl12xx_allocate_link
(
struct
wl1271
*
wl
,
u8
*
hlid
)
{
u8
link
=
find_first_zero_bit
(
wl
->
links_map
,
WL12XX_MAX_LINKS
);
if
(
link
>=
WL12XX_MAX_LINKS
)
return
-
EBUSY
;
__set_bit
(
link
,
wl
->
links_map
);
*
hlid
=
link
;
return
0
;
}
static
void
wl12xx_free_link
(
struct
wl1271
*
wl
,
u8
*
hlid
)
{
if
(
*
hlid
==
WL12XX_INVALID_LINK_ID
)
return
;
__clear_bit
(
*
hlid
,
wl
->
links_map
);
*
hlid
=
WL12XX_INVALID_LINK_ID
;
}
static
int
wl12xx_get_new_session_id
(
struct
wl1271
*
wl
)
{
if
(
wl
->
session_counter
>=
SESSION_COUNTER_MAX
)
wl
->
session_counter
=
0
;
wl
->
session_counter
++
;
/* Reverse order BSSID */
bssid
=
(
u8
*
)
&
join
->
bssid_lsb
;
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
bssid
[
i
]
=
wl
->
bssid
[
ETH_ALEN
-
i
-
1
];
return
wl
->
session_counter
;
}
int
wl12xx_cmd_role_start_dev
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
join
->
rx_config_options
=
cpu_to_le32
(
wl
->
rx_config
);
join
->
rx_filter_options
=
cpu_to_le32
(
wl
->
rx_filter
);
join
->
bss_type
=
bss_type
;
join
->
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
join
->
supported_rate_set
=
cpu_to_le32
(
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"cmd role start dev %d"
,
wl
->
dev_role_id
);
cmd
->
role_id
=
wl
->
dev_role_id
;
if
(
wl
->
band
==
IEEE80211_BAND_5GHZ
)
join
->
bss_type
|=
WL1271_JOIN_CMD_BSS_TYPE_5GHZ
;
cmd
->
band
=
WL12XX_BAND_5GHZ
;
cmd
->
channel
=
wl
->
channel
;
if
(
wl
->
dev_hlid
==
WL12XX_INVALID_LINK_ID
)
{
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
dev_hlid
);
if
(
ret
)
goto
out_free
;
}
cmd
->
device
.
hlid
=
wl
->
dev_hlid
;
cmd
->
device
.
session
=
wl
->
session_counter
;
wl1271_debug
(
DEBUG_CMD
,
"role start: roleid=%d, hlid=%d, session=%d"
,
cmd
->
role_id
,
cmd
->
device
.
hlid
,
cmd
->
device
.
session
);
join
->
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
join
->
dtim_interval
=
WL1271_DEFAULT_DTIM_PERIOD
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role enable"
);
goto
err_hlid
;
}
goto
out_free
;
err_hlid:
/* clear links on error */
__clear_bit
(
wl
->
dev_hlid
,
wl
->
links_map
);
wl
->
dev_hlid
=
WL12XX_INVALID_LINK_ID
;
out_free:
kfree
(
cmd
);
join
->
channel
=
wl
->
channel
;
join
->
ssid_len
=
wl
->
ssid_len
;
memcpy
(
join
->
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
out:
return
ret
;
}
join
->
ctrl
|=
wl
->
session_counter
<<
WL1271_JOIN_CMD_TX_SESSION_OFFSET
;
int
wl12xx_cmd_role_stop_dev
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_stop
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd join: basic_rate_set=0x%x, rate_set=0x%x"
,
join
->
basic_rate_set
,
join
->
supported_rate_set
)
;
if
(
WARN_ON
(
wl
->
dev_hlid
==
WL12XX_INVALID_LINK_ID
))
return
-
EINVAL
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_START_JOIN
,
join
,
sizeof
(
*
join
),
0
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role stop dev"
);
cmd
->
role_id
=
wl
->
dev_role_id
;
cmd
->
disc_type
=
DISCONNECT_IMMEDIATE
;
cmd
->
reason
=
cpu_to_le16
(
WLAN_REASON_UNSPECIFIED
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd
join
"
);
wl1271_error
(
"failed to initiate cmd
role stop
"
);
goto
out_free
;
}
ret
=
wl1271_cmd_wait_for_event
(
wl
,
JOIN_EVENT_COMPLETE_ID
);
ret
=
wl1271_cmd_wait_for_event
(
wl
,
DISCONNECT_EVENT_COMPLETE_ID
);
if
(
ret
<
0
)
{
wl1271_error
(
"cmd role stop dev event completion error"
);
goto
out_free
;
}
wl12xx_free_link
(
wl
,
&
wl
->
dev_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_start_sta
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role start sta %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
if
(
wl
->
band
==
IEEE80211_BAND_5GHZ
)
cmd
->
band
=
WL12XX_BAND_5GHZ
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
sta
.
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
sta
.
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
sta
.
ssid_type
=
WL12XX_SSID_TYPE_ANY
;
cmd
->
sta
.
ssid_len
=
wl
->
ssid_len
;
memcpy
(
cmd
->
sta
.
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
memcpy
(
cmd
->
sta
.
bssid
,
wl
->
bssid
,
ETH_ALEN
);
cmd
->
sta
.
local_rates
=
cpu_to_le32
(
wl
->
rate_set
);
if
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
{
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
sta_hlid
);
if
(
ret
)
goto
out_free
;
}
cmd
->
sta
.
hlid
=
wl
->
sta_hlid
;
cmd
->
sta
.
session
=
wl12xx_get_new_session_id
(
wl
);
cmd
->
sta
.
remote_rates
=
cpu_to_le32
(
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"role start: roleid=%d, hlid=%d, session=%d "
"basic_rate_set: 0x%x, remote_rates: 0x%x"
,
wl
->
role_id
,
cmd
->
sta
.
hlid
,
cmd
->
sta
.
session
,
wl
->
basic_rate_set
,
wl
->
rate_set
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role start sta"
);
goto
err_hlid
;
}
goto
out_free
;
err_hlid:
/* clear links on error. */
wl12xx_free_link
(
wl
,
&
wl
->
sta_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
/* use this function to stop ibss as well */
int
wl12xx_cmd_role_stop_sta
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_stop
*
cmd
;
int
ret
;
if
(
WARN_ON
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
))
return
-
EINVAL
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role stop sta %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
cmd
->
disc_type
=
DISCONNECT_IMMEDIATE
;
cmd
->
reason
=
cpu_to_le16
(
WLAN_REASON_UNSPECIFIED
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role stop sta"
);
goto
out_free
;
}
wl12xx_free_link
(
wl
,
&
wl
->
sta_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_start_ap
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
struct
ieee80211_bss_conf
*
bss_conf
=
&
wl
->
vif
->
bss_conf
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd role start ap %d"
,
wl
->
role_id
);
/*
* We currently do not support hidden SSID. The real SSID
* should be fetched from mac80211 first.
*/
if
(
wl
->
ssid_len
==
0
)
{
wl1271_warning
(
"Hidden SSID currently not supported for AP"
);
ret
=
-
EINVAL
;
goto
out
;
}
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
ap_global_hlid
);
if
(
ret
<
0
)
wl1271_error
(
"cmd join event completion error"
);
goto
out_free
;
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
ap_bcast_hlid
);
if
(
ret
<
0
)
goto
out_free_global
;
cmd
->
role_id
=
wl
->
role_id
;
cmd
->
ap
.
aging_period
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_aging_period
);
cmd
->
ap
.
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
ap
.
global_hlid
=
wl
->
ap_global_hlid
;
cmd
->
ap
.
broadcast_hlid
=
wl
->
ap_bcast_hlid
;
cmd
->
ap
.
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
ap
.
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
ap
.
dtim_interval
=
bss_conf
->
dtim_period
;
cmd
->
ap
.
beacon_expiry
=
WL1271_AP_DEF_BEACON_EXP
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
ap
.
ssid_len
=
wl
->
ssid_len
;
cmd
->
ap
.
ssid_type
=
WL12XX_SSID_TYPE_PUBLIC
;
memcpy
(
cmd
->
ap
.
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
cmd
->
ap
.
local_rates
=
cpu_to_le32
(
0xffffffff
);
switch
(
wl
->
band
)
{
case
IEEE80211_BAND_2GHZ
:
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
case
IEEE80211_BAND_5GHZ
:
cmd
->
band
=
RADIO_BAND_5GHZ
;
break
;
default:
wl1271_warning
(
"ap start - unknown band: %d"
,
(
int
)
wl
->
band
);
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
}
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role start ap"
);
goto
out_free_bcast
;
}
goto
out_free
;
out_free_bcast:
wl12xx_free_link
(
wl
,
&
wl
->
ap_bcast_hlid
);
out_free_global:
wl12xx_free_link
(
wl
,
&
wl
->
ap_global_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_stop_ap
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_stop
*
cmd
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role stop ap %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role stop ap"
);
goto
out_free
;
}
wl12xx_free_link
(
wl
,
&
wl
->
ap_bcast_hlid
);
wl12xx_free_link
(
wl
,
&
wl
->
ap_global_hlid
);
out_free:
kfree
(
join
);
kfree
(
cmd
);
out:
return
ret
;
}
int
wl12xx_cmd_role_start_ibss
(
struct
wl1271
*
wl
)
{
struct
wl12xx_cmd_role_start
*
cmd
;
struct
ieee80211_bss_conf
*
bss_conf
=
&
wl
->
vif
->
bss_conf
;
int
ret
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd role start ibss %d"
,
wl
->
role_id
);
cmd
->
role_id
=
wl
->
role_id
;
if
(
wl
->
band
==
IEEE80211_BAND_5GHZ
)
cmd
->
band
=
WL12XX_BAND_5GHZ
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
ibss
.
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
ibss
.
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
ibss
.
dtim_interval
=
bss_conf
->
dtim_period
;
cmd
->
ibss
.
ssid_type
=
WL12XX_SSID_TYPE_ANY
;
cmd
->
ibss
.
ssid_len
=
wl
->
ssid_len
;
memcpy
(
cmd
->
ibss
.
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
memcpy
(
cmd
->
ibss
.
bssid
,
wl
->
bssid
,
ETH_ALEN
);
cmd
->
sta
.
local_rates
=
cpu_to_le32
(
wl
->
rate_set
);
if
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
{
ret
=
wl12xx_allocate_link
(
wl
,
&
wl
->
sta_hlid
);
if
(
ret
)
goto
out_free
;
}
cmd
->
ibss
.
hlid
=
wl
->
sta_hlid
;
cmd
->
ibss
.
remote_rates
=
cpu_to_le32
(
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"role start: roleid=%d, hlid=%d, session=%d "
"basic_rate_set: 0x%x, remote_rates: 0x%x"
,
wl
->
role_id
,
cmd
->
sta
.
hlid
,
cmd
->
sta
.
session
,
wl
->
basic_rate_set
,
wl
->
rate_set
);
wl1271_debug
(
DEBUG_CMD
,
"wl->bssid = %pM"
,
wl
->
bssid
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ROLE_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd role enable"
);
goto
err_hlid
;
}
goto
out_free
;
err_hlid:
/* clear links on error. */
wl12xx_free_link
(
wl
,
&
wl
->
sta_hlid
);
out_free:
kfree
(
cmd
);
out:
return
ret
;
}
/**
* send test command to firmware
*
...
...
@@ -567,6 +974,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
goto
out
;
}
ps_params
->
role_id
=
wl
->
role_id
;
ps_params
->
ps_mode
=
ps_mode
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_PS_MODE
,
ps_params
,
...
...
@@ -813,9 +1221,9 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
wl
->
basic_rate
);
}
int
wl12
71_cmd_set_sta_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
int
wl12
xx_cmd_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
,
u8
hl
id
)
{
struct
wl1271_cmd_set_
sta_
keys
*
cmd
;
struct
wl1271_cmd_set_keys
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd set_default_wep_key %d"
,
id
);
...
...
@@ -826,36 +1234,7 @@ int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id)
goto
out
;
}
cmd
->
id
=
id
;
cmd
->
key_action
=
cpu_to_le16
(
KEY_SET_ID
);
cmd
->
key_type
=
KEY_WEP
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_KEYS
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_warning
(
"cmd set_default_wep_key failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
cmd
);
return
ret
;
}
int
wl1271_cmd_set_ap_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
{
struct
wl1271_cmd_set_ap_keys
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd set_ap_default_wep_key %d"
,
id
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
hlid
=
WL1271_AP_BROADCAST_HLID
;
cmd
->
hlid
=
hlid
;
cmd
->
key_id
=
id
;
cmd
->
lid_key_type
=
WEP_DEFAULT_LID_TYPE
;
cmd
->
key_action
=
cpu_to_le16
(
KEY_SET_ID
);
...
...
@@ -863,7 +1242,7 @@ int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id)
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_KEYS
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_warning
(
"cmd set_
ap_
default_wep_key failed: %d"
,
ret
);
wl1271_warning
(
"cmd set_default_wep_key failed: %d"
,
ret
);
goto
out
;
}
...
...
@@ -877,17 +1256,27 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
u8
key_size
,
const
u8
*
key
,
const
u8
*
addr
,
u32
tx_seq_32
,
u16
tx_seq_16
)
{
struct
wl1271_cmd_set_
sta_
keys
*
cmd
;
struct
wl1271_cmd_set_keys
*
cmd
;
int
ret
=
0
;
/* hlid might have already been deleted */
if
(
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
return
0
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
if
(
key_type
!=
KEY_WEP
)
memcpy
(
cmd
->
addr
,
addr
,
ETH_ALEN
);
cmd
->
hlid
=
wl
->
sta_hlid
;
if
(
key_type
==
KEY_WEP
)
cmd
->
lid_key_type
=
WEP_DEFAULT_LID_TYPE
;
else
if
(
is_broadcast_ether_addr
(
addr
))
cmd
->
lid_key_type
=
BROADCAST_LID_TYPE
;
else
cmd
->
lid_key_type
=
UNICAST_LID_TYPE
;
cmd
->
key_action
=
cpu_to_le16
(
action
);
cmd
->
key_size
=
key_size
;
...
...
@@ -896,10 +1285,7 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
cmd
->
ac_seq_num16
[
0
]
=
cpu_to_le16
(
tx_seq_16
);
cmd
->
ac_seq_num32
[
0
]
=
cpu_to_le32
(
tx_seq_32
);
/* we have only one SSID profile */
cmd
->
ssid_profile
=
0
;
cmd
->
id
=
id
;
cmd
->
key_id
=
id
;
if
(
key_type
==
KEY_TKIP
)
{
/*
...
...
@@ -930,11 +1316,15 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
return
ret
;
}
/*
* TODO: merge with sta/ibss into 1 set_key function.
* note there are slight diffs
*/
int
wl1271_cmd_set_ap_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
u8
hlid
,
u32
tx_seq_32
,
u16
tx_seq_16
)
{
struct
wl1271_cmd_set_
ap_
keys
*
cmd
;
struct
wl1271_cmd_set_keys
*
cmd
;
int
ret
=
0
;
u8
lid_type
;
...
...
@@ -942,7 +1332,7 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
if
(
!
cmd
)
return
-
ENOMEM
;
if
(
hlid
==
WL1271_AP_BROADCAST_HLID
)
{
if
(
hlid
==
wl
->
ap_bcast_hlid
)
{
if
(
key_type
==
KEY_WEP
)
lid_type
=
WEP_DEFAULT_LID_TYPE
;
else
...
...
@@ -991,12 +1381,12 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
return
ret
;
}
int
wl12
71_cmd_disconnect
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_set_peer_state
(
struct
wl1271
*
wl
,
u8
hlid
)
{
struct
wl12
71_cmd_disconnect
*
cmd
;
struct
wl12
xx_cmd_set_peer_state
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
disconnect"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
set peer state (hlid=%d)"
,
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1004,21 +1394,15 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
goto
out
;
}
cmd
->
rx_config_options
=
cpu_to_le32
(
wl
->
rx_config
);
cmd
->
rx_filter_options
=
cpu_to_le32
(
wl
->
rx_filter
);
/* disconnect reason is not used in immediate disconnections */
cmd
->
type
=
DISCONNECT_IMMEDIATE
;
cmd
->
hlid
=
hlid
;
cmd
->
state
=
WL1271_CMD_STA_STATE_CONNECTED
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_
DISCONNECT
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_
SET_PEER_STATE
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to send
disconnect
command"
);
wl1271_error
(
"failed to send
set peer state
command"
);
goto
out_free
;
}
ret
=
wl1271_cmd_wait_for_event
(
wl
,
DISCONNECT_EVENT_COMPLETE_ID
);
if
(
ret
<
0
)
wl1271_error
(
"cmd disconnect event completion error"
);
out_free:
kfree
(
cmd
);
...
...
@@ -1026,12 +1410,13 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_set_sta_state
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_add_peer
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
)
{
struct
wl1271_cmd_set_sta_state
*
cmd
;
int
ret
=
0
;
struct
wl12xx_cmd_add_peer
*
cmd
;
int
ret
;
u32
sta_rates
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
set sta state"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
add peer %d"
,
(
int
)
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1039,11 +1424,27 @@ int wl1271_cmd_set_sta_state(struct wl1271 *wl)
goto
out
;
}
cmd
->
state
=
WL1271_CMD_STA_STATE_CONNECTED
;
/* currently we don't support UAPSD */
cmd
->
sp_len
=
0
;
memcpy
(
cmd
->
addr
,
sta
->
addr
,
ETH_ALEN
);
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
aid
=
sta
->
aid
;
cmd
->
hlid
=
hlid
;
cmd
->
wmm
=
sta
->
wme
?
1
:
0
;
sta_rates
=
sta
->
supp_rates
[
wl
->
band
];
if
(
sta
->
ht_cap
.
ht_supported
)
sta_rates
|=
sta
->
ht_cap
.
mcs
.
rx_mask
[
0
]
<<
HW_HT_RATES_OFFSET
;
cmd
->
supported_rates
=
cpu_to_le32
(
wl1271_tx_enabled_rates_get
(
wl
,
sta_rates
));
ret
=
wl1271_cmd_send
(
wl
,
CMD_SET_STA_STATE
,
cmd
,
sizeof
(
*
cmd
),
0
);
wl1271_debug
(
DEBUG_CMD
,
"new peer rates: 0x%x"
,
cmd
->
supported_rates
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ADD_PEER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
send set STA state command
"
);
wl1271_error
(
"failed to
initiate cmd add peer
"
);
goto
out_free
;
}
...
...
@@ -1054,23 +1455,12 @@ int wl1271_cmd_set_sta_state(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_start_bss
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_remove_peer
(
struct
wl1271
*
wl
,
u8
hlid
)
{
struct
wl1271_cmd_bss_start
*
cmd
;
struct
ieee80211_bss_conf
*
bss_conf
=
&
wl
->
vif
->
bss_conf
;
struct
wl12xx_cmd_remove_peer
*
cmd
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd start bss"
);
/*
* FIXME: We currently do not support hidden SSID. The real SSID
* should be fetched from mac80211 first.
*/
if
(
wl
->
ssid_len
==
0
)
{
wl1271_warning
(
"Hidden SSID currently not supported for AP"
);
ret
=
-
EINVAL
;
goto
out
;
}
wl1271_debug
(
DEBUG_CMD
,
"cmd remove peer %d"
,
(
int
)
hlid
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1078,40 +1468,24 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
goto
out
;
}
memcpy
(
cmd
->
bssid
,
bss_conf
->
bssid
,
ETH_ALEN
);
cmd
->
aging_period
=
cpu_to_le16
(
wl
->
conf
.
tx
.
ap_aging_period
);
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
global_hlid
=
WL1271_AP_GLOBAL_HLID
;
cmd
->
broadcast_hlid
=
WL1271_AP_BROADCAST_HLID
;
cmd
->
basic_rate_set
=
cpu_to_le32
(
wl
->
basic_rate_set
);
cmd
->
beacon_interval
=
cpu_to_le16
(
wl
->
beacon_int
);
cmd
->
dtim_interval
=
bss_conf
->
dtim_period
;
cmd
->
beacon_expiry
=
WL1271_AP_DEF_BEACON_EXP
;
cmd
->
channel
=
wl
->
channel
;
cmd
->
ssid_len
=
wl
->
ssid_len
;
cmd
->
ssid_type
=
SSID_TYPE_PUBLIC
;
memcpy
(
cmd
->
ssid
,
wl
->
ssid
,
wl
->
ssid_len
);
switch
(
wl
->
band
)
{
case
IEEE80211_BAND_2GHZ
:
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
case
IEEE80211_BAND_5GHZ
:
cmd
->
band
=
RADIO_BAND_5GHZ
;
break
;
default:
wl1271_warning
(
"bss start - unknown band: %d"
,
(
int
)
wl
->
band
);
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
}
cmd
->
hlid
=
hlid
;
/* We never send a deauth, mac80211 is in charge of this */
cmd
->
reason_opcode
=
0
;
cmd
->
send_deauth_flag
=
0
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_
BSS_START
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_
REMOVE_PEER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to initiate cmd
start bss
"
);
wl1271_error
(
"failed to initiate cmd
remove peer
"
);
goto
out_free
;
}
/*
* We are ok with a timeout here. The event is sometimes not sent
* due to a firmware bug.
*/
wl1271_cmd_wait_for_event_or_timeout
(
wl
,
PEER_REMOVE_COMPLETE_EVENT_ID
);
out_free:
kfree
(
cmd
);
...
...
@@ -1119,12 +1493,12 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_stop_bss
(
struct
wl1271
*
wl
)
int
wl12
xx_cmd_config_fwlog
(
struct
wl1271
*
wl
)
{
struct
wl12
71_cmd_bss_start
*
cmd
;
int
ret
;
struct
wl12
xx_cmd_config_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
stop bss
"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
config firmware logger
"
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1132,11 +1506,15 @@ int wl1271_cmd_stop_bss(struct wl1271 *wl)
goto
out
;
}
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
logger_mode
=
wl
->
conf
.
fwlog
.
mode
;
cmd
->
log_severity
=
wl
->
conf
.
fwlog
.
severity
;
cmd
->
timestamp
=
wl
->
conf
.
fwlog
.
timestamp
;
cmd
->
output
=
wl
->
conf
.
fwlog
.
output
;
cmd
->
threshold
=
wl
->
conf
.
fwlog
.
threshold
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_
BSS_STOP
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_
CONFIG_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
initiate cmd stop bss
"
);
wl1271_error
(
"failed to
send config firmware logger command
"
);
goto
out_free
;
}
...
...
@@ -1147,12 +1525,12 @@ int wl1271_cmd_stop_bss(struct wl1271 *wl)
return
ret
;
}
int
wl12
71_cmd_add_sta
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
)
int
wl12
xx_cmd_start_fwlog
(
struct
wl1271
*
wl
)
{
struct
wl12
71_cmd_add_sta
*
cmd
;
int
ret
;
struct
wl12
xx_cmd_start_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
add sta %d"
,
(
int
)
hlid
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
start firmware logger"
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1160,23 +1538,9 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
goto
out
;
}
/* currently we don't support UAPSD */
cmd
->
sp_len
=
0
;
memcpy
(
cmd
->
addr
,
sta
->
addr
,
ETH_ALEN
);
cmd
->
bss_index
=
WL1271_AP_BSS_INDEX
;
cmd
->
aid
=
sta
->
aid
;
cmd
->
hlid
=
hlid
;
cmd
->
wmm
=
sta
->
wme
?
1
:
0
;
cmd
->
supported_rates
=
cpu_to_le32
(
wl1271_tx_enabled_rates_get
(
wl
,
sta
->
supp_rates
[
wl
->
band
]));
wl1271_debug
(
DEBUG_CMD
,
"new sta rates: 0x%x"
,
cmd
->
supported_rates
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ADD_STA
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_START_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
initiate cmd add sta
"
);
wl1271_error
(
"failed to
send start firmware logger command
"
);
goto
out_free
;
}
...
...
@@ -1187,12 +1551,12 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
return
ret
;
}
int
wl12
71_cmd_remove_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
int
wl12
xx_cmd_stop_fwlog
(
struct
wl1271
*
wl
)
{
struct
wl12
71_cmd_remove_sta
*
cmd
;
int
ret
;
struct
wl12
xx_cmd_stop_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
remove sta %d"
,
(
int
)
hlid
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
stop firmware logger"
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1200,23 +1564,12 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
goto
out
;
}
cmd
->
hlid
=
hlid
;
/* We never send a deauth, mac80211 is in charge of this */
cmd
->
reason_opcode
=
0
;
cmd
->
send_deauth_flag
=
0
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_REMOVE_STA
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_STOP_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to
initiate cmd remove sta
"
);
wl1271_error
(
"failed to
send stop firmware logger command
"
);
goto
out_free
;
}
/*
* We are ok with a timeout here. The event is sometimes not sent
* due to a firmware bug.
*/
wl1271_cmd_wait_for_event_or_timeout
(
wl
,
STA_REMOVE_COMPLETE_EVENT_ID
);
out_free:
kfree
(
cmd
);
...
...
@@ -1224,12 +1577,15 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
return
ret
;
}
int
wl12xx_cmd_config_fwlog
(
struct
wl1271
*
wl
)
static
int
wl12xx_cmd_roc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
struct
wl12xx_cmd_
config_fwlog
*
cmd
;
struct
wl12xx_cmd_
roc
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd config firmware logger"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd roc %d (%d)"
,
wl
->
channel
,
role_id
);
if
(
WARN_ON
(
role_id
==
WL12XX_INVALID_ROLE_ID
))
return
-
EINVAL
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
...
...
@@ -1237,15 +1593,25 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
goto
out
;
}
cmd
->
logger_mode
=
wl
->
conf
.
fwlog
.
mode
;
cmd
->
log_severity
=
wl
->
conf
.
fwlog
.
severity
;
cmd
->
timestamp
=
wl
->
conf
.
fwlog
.
timestamp
;
cmd
->
output
=
wl
->
conf
.
fwlog
.
output
;
cmd
->
threshold
=
wl
->
conf
.
fwlog
.
threshold
;
cmd
->
role_id
=
role_id
;
cmd
->
channel
=
wl
->
channel
;
switch
(
wl
->
band
)
{
case
IEEE80211_BAND_2GHZ
:
cmd
->
band
=
RADIO_BAND_2_4GHZ
;
break
;
case
IEEE80211_BAND_5GHZ
:
cmd
->
band
=
RADIO_BAND_5GHZ
;
break
;
default:
wl1271_error
(
"roc - unknown band: %d"
,
(
int
)
wl
->
band
);
ret
=
-
EINVAL
;
goto
out_free
;
}
ret
=
wl1271_cmd_send
(
wl
,
CMD_CONFIG_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_REMAIN_ON_CHANNEL
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to send
config firmware logger
command"
);
wl1271_error
(
"failed to send
ROC
command"
);
goto
out_free
;
}
...
...
@@ -1256,22 +1622,24 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
return
ret
;
}
int
wl12xx_cmd_start_fwlog
(
struct
wl1271
*
wl
)
static
int
wl12xx_cmd_croc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
struct
wl12xx_cmd_
start_fwlog
*
cmd
;
struct
wl12xx_cmd_
croc
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd
start firmware logger"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd
croc (%d)"
,
role_id
);
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
cmd
->
role_id
=
role_id
;
ret
=
wl1271_cmd_send
(
wl
,
CMD_START_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_CANCEL_REMAIN_ON_CHANNEL
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"failed to send
start firmware logger
command"
);
wl1271_error
(
"failed to send
ROC
command"
);
goto
out_free
;
}
...
...
@@ -1282,28 +1650,41 @@ int wl12xx_cmd_start_fwlog(struct wl1271 *wl)
return
ret
;
}
int
wl12xx_
cmd_stop_fwlog
(
struct
wl1271
*
wl
)
int
wl12xx_
roc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
struct
wl12xx_cmd_stop_fwlog
*
cmd
;
int
ret
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd stop firmware logger"
);
if
(
WARN_ON
(
test_bit
(
role_id
,
wl
->
roc_map
)))
return
0
;
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
ret
=
wl12xx_cmd_roc
(
wl
,
role_id
);
if
(
ret
<
0
)
goto
out
;
}
ret
=
wl1271_cmd_send
(
wl
,
CMD_STOP_FWLOGGER
,
cmd
,
sizeof
(
*
cmd
),
0
);
ret
=
wl1271_cmd_wait_for_event
(
wl
,
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID
);
if
(
ret
<
0
)
{
wl1271_error
(
"
failed to send stop firmware logger command
"
);
goto
out
_free
;
wl1271_error
(
"
cmd roc event completion error
"
);
goto
out
;
}
out_free:
kfree
(
cmd
);
__set_bit
(
role_id
,
wl
->
roc_map
);
out:
return
ret
;
}
int
wl12xx_croc
(
struct
wl1271
*
wl
,
u8
role_id
)
{
int
ret
=
0
;
if
(
WARN_ON
(
!
test_bit
(
role_id
,
wl
->
roc_map
)))
return
0
;
ret
=
wl12xx_cmd_croc
(
wl
,
role_id
);
if
(
ret
<
0
)
goto
out
;
__clear_bit
(
role_id
,
wl
->
roc_map
);
out:
return
ret
;
}
drivers/net/wireless/wl12xx/cmd.h
浏览文件 @
e0a8c583
...
...
@@ -36,7 +36,15 @@ int wl128x_cmd_general_parms(struct wl1271 *wl);
int
wl1271_cmd_radio_parms
(
struct
wl1271
*
wl
);
int
wl128x_cmd_radio_parms
(
struct
wl1271
*
wl
);
int
wl1271_cmd_ext_radio_parms
(
struct
wl1271
*
wl
);
int
wl1271_cmd_join
(
struct
wl1271
*
wl
,
u8
bss_type
);
int
wl12xx_cmd_role_enable
(
struct
wl1271
*
wl
,
u8
role_type
,
u8
*
role_id
);
int
wl12xx_cmd_role_disable
(
struct
wl1271
*
wl
,
u8
*
role_id
);
int
wl12xx_cmd_role_start_dev
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_stop_dev
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_start_sta
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_stop_sta
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_start_ap
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_stop_ap
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_role_start_ibss
(
struct
wl1271
*
wl
);
int
wl1271_cmd_test
(
struct
wl1271
*
wl
,
void
*
buf
,
size_t
buf_len
,
u8
answer
);
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
);
...
...
@@ -56,20 +64,18 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
int
wl1271_cmd_build_arp_rsp
(
struct
wl1271
*
wl
,
__be32
ip_addr
);
int
wl1271_build_qos_null_data
(
struct
wl1271
*
wl
);
int
wl1271_cmd_build_klv_null_data
(
struct
wl1271
*
wl
);
int
wl1271_cmd_set_sta_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
int
wl1271_cmd_set_ap_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
);
int
wl12xx_cmd_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
,
u8
hlid
);
int
wl1271_cmd_set_sta_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
const
u8
*
addr
,
u32
tx_seq_32
,
u16
tx_seq_16
);
int
wl1271_cmd_set_ap_key
(
struct
wl1271
*
wl
,
u16
action
,
u8
id
,
u8
key_type
,
u8
key_size
,
const
u8
*
key
,
u8
hlid
,
u32
tx_seq_32
,
u16
tx_seq_16
);
int
wl1271_cmd_disconnect
(
struct
wl1271
*
wl
);
int
wl1271_cmd_set_sta_state
(
struct
wl1271
*
wl
);
int
wl1271_cmd_start_bss
(
struct
wl1271
*
wl
);
int
wl1271_cmd_stop_bss
(
struct
wl1271
*
wl
);
int
wl1271_cmd_add_sta
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
);
int
wl1271_cmd_remove_sta
(
struct
wl1271
*
wl
,
u8
hlid
);
int
wl12xx_cmd_set_peer_state
(
struct
wl1271
*
wl
,
u8
hlid
);
int
wl12xx_roc
(
struct
wl1271
*
wl
,
u8
role_id
);
int
wl12xx_croc
(
struct
wl1271
*
wl
,
u8
role_id
);
int
wl12xx_cmd_add_peer
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
);
int
wl12xx_cmd_remove_peer
(
struct
wl1271
*
wl
,
u8
hlid
);
int
wl12xx_cmd_config_fwlog
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_start_fwlog
(
struct
wl1271
*
wl
);
int
wl12xx_cmd_stop_fwlog
(
struct
wl1271
*
wl
);
...
...
@@ -83,25 +89,21 @@ enum wl1271_commands {
CMD_DISABLE_TX
=
6
,
CMD_SCAN
=
8
,
CMD_STOP_SCAN
=
9
,
CMD_START_JOIN
=
11
,
CMD_SET_KEYS
=
12
,
CMD_READ_MEMORY
=
13
,
CMD_WRITE_MEMORY
=
14
,
CMD_SET_TEMPLATE
=
19
,
CMD_TEST
=
23
,
CMD_NOISE_HIST
=
28
,
CMD_
LNA_CONTROL
=
32
,
CMD_
QUIET_ELEMENT_SET_STATE
=
29
,
CMD_SET_BCN_MODE
=
33
,
CMD_MEASUREMENT
=
34
,
CMD_STOP_MEASUREMENT
=
35
,
CMD_DISCONNECT
=
36
,
CMD_SET_PS_MODE
=
37
,
CMD_CHANNEL_SWITCH
=
38
,
CMD_STOP_CHANNEL_SWICTH
=
39
,
CMD_AP_DISCOVERY
=
40
,
CMD_STOP_AP_DISCOVERY
=
41
,
CMD_SPS_SCAN
=
42
,
CMD_STOP_SPS_SCAN
=
43
,
CMD_HEALTH_CHECK
=
45
,
CMD_DEBUG
=
46
,
CMD_TRIGGER_SCAN_TO
=
47
,
...
...
@@ -109,16 +111,30 @@ enum wl1271_commands {
CMD_CONNECTION_SCAN_SSID_CFG
=
49
,
CMD_START_PERIODIC_SCAN
=
50
,
CMD_STOP_PERIODIC_SCAN
=
51
,
CMD_SET_STA_STATE
=
52
,
CMD_CONFIG_FWLOGGER
=
53
,
CMD_START_FWLOGGER
=
54
,
CMD_STOP_FWLOGGER
=
55
,
CMD_SET_PEER_STATE
=
52
,
CMD_REMAIN_ON_CHANNEL
=
53
,
CMD_CANCEL_REMAIN_ON_CHANNEL
=
54
,
/* AP mode commands */
CMD_BSS_START
=
60
,
CMD_BSS_STOP
=
61
,
CMD_ADD_STA
=
62
,
CMD_REMOVE_STA
=
63
,
CMD_CONFIG_FWLOGGER
=
55
,
CMD_START_FWLOGGER
=
56
,
CMD_STOP_FWLOGGER
=
57
,
/* AP commands */
CMD_ADD_PEER
=
62
,
CMD_REMOVE_PEER
=
63
,
/* Role API */
CMD_ROLE_ENABLE
=
70
,
CMD_ROLE_DISABLE
=
71
,
CMD_ROLE_START
=
72
,
CMD_ROLE_STOP
=
73
,
/* WIFI Direct */
CMD_WFD_START_DISCOVERY
=
80
,
CMD_WFD_STOP_DISCOVERY
=
81
,
CMD_WFD_ATTRIBUTE_CONFIG
=
82
,
CMD_NOP
=
100
,
NUM_COMMANDS
,
MAX_COMMAND_ID
=
0xFFFF
,
...
...
@@ -147,21 +163,20 @@ enum cmd_templ {
CMD_TEMPL_CTS
,
/*
* For CTS-to-self (FastCTS) mechanism
* for BT/WLAN coexistence (SoftGemini). */
CMD_TEMPL_ARP_RSP
,
CMD_TEMPL_LINK_MEASUREMENT_REPORT
,
/* AP-mode specific */
CMD_TEMPL_AP_BEACON
=
13
,
CMD_TEMPL_AP_BEACON
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
CMD_TEMPL_A
P_A
RP_RSP
,
CMD_TEMPL_ARP_RSP
,
CMD_TEMPL_DEAUTH_AP
,
CMD_TEMPL_TEMPORARY
,
CMD_TEMPL_LINK_MEASUREMENT_REPORT
,
CMD_TEMPL_MAX
=
0xff
};
/* unit ms */
#define WL1271_COMMAND_TIMEOUT 2000
#define WL1271_CMD_TEMPL_MAX_SIZE 252
#define WL1271_CMD_TEMPL_DFLT_SIZE 252
#define WL1271_CMD_TEMPL_MAX_SIZE 548
#define WL1271_EVENT_TIMEOUT 750
struct
wl1271_cmd_header
{
...
...
@@ -193,6 +208,8 @@ enum {
CMD_STATUS_WRONG_NESTING
=
19
,
CMD_STATUS_TIMEOUT
=
21
,
/* Driver internal use.*/
CMD_STATUS_FW_RESET
=
22
,
/* Driver internal use.*/
CMD_STATUS_TEMPLATE_OOM
=
23
,
CMD_STATUS_NO_RX_BA_SESSION
=
24
,
MAX_COMMAND_STATUS
=
0xff
};
...
...
@@ -210,38 +227,114 @@ enum {
#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1
#define WL1271_JOIN_CMD_BSS_TYPE_5GHZ 0x10
struct
wl12
71_cmd_join
{
struct
wl12
xx_cmd_role_enable
{
struct
wl1271_cmd_header
header
;
__le32
bssid_lsb
;
__le16
bssid_msb
;
__le16
beacon_interval
;
/* in TBTTs */
__le32
rx_config_options
;
__le32
rx_filter_options
;
u8
role_id
;
u8
role_type
;
u8
mac_address
[
ETH_ALEN
];
}
__packed
;
/*
* The target uses this field to determine the rate at
* which to transmit control frame responses (such as
* ACK or CTS frames).
*/
__le32
basic_rate_set
;
__le32
supported_rate_set
;
u8
dtim_interval
;
/*
* bits 0-2: This bitwise field specifies the type
* of BSS to start or join (BSS_TYPE_*).
* bit 4: Band - The radio band in which to join
* or start.
* 0 - 2.4GHz band
* 1 - 5GHz band
* bits 3, 5-7: Reserved
*/
u8
bss_type
;
struct
wl12xx_cmd_role_disable
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
padding
[
3
];
}
__packed
;
enum
wl12xx_band
{
WL12XX_BAND_2_4GHZ
=
0
,
WL12XX_BAND_5GHZ
=
1
,
WL12XX_BAND_JAPAN_4_9_GHZ
=
2
,
WL12XX_BAND_DEFAULT
=
WL12XX_BAND_2_4GHZ
,
WL12XX_BAND_INVALID
=
0x7E
,
WL12XX_BAND_MAX_RADIO
=
0x7F
,
};
struct
wl12xx_cmd_role_start
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
band
;
u8
channel
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
ctrl
;
/* JOIN_CMD_CTRL_* */
u8
reserved
[
3
];
u8
padding
;
union
{
struct
{
u8
hlid
;
u8
session
;
u8
padding_1
[
54
];
}
__packed
device
;
/* sta & p2p_cli use the same struct */
struct
{
u8
bssid
[
ETH_ALEN
];
u8
hlid
;
/* data hlid */
u8
session
;
__le32
remote_rates
;
/* remote supported rates */
/*
* The target uses this field to determine the rate at
* which to transmit control frame responses (such as
* ACK or CTS frames).
*/
__le32
basic_rate_set
;
__le32
local_rates
;
/* local supported rates */
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
__le16
beacon_interval
;
/* in TBTTs */
}
__packed
sta
;
struct
{
u8
bssid
[
ETH_ALEN
];
u8
hlid
;
/* data hlid */
u8
dtim_interval
;
__le32
remote_rates
;
/* remote supported rates */
__le32
basic_rate_set
;
__le32
local_rates
;
/* local supported rates */
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
__le16
beacon_interval
;
/* in TBTTs */
u8
padding_1
[
4
];
}
__packed
ibss
;
/* ap & p2p_go use the same struct */
struct
{
__le16
aging_period
;
/* in secs */
u8
beacon_expiry
;
/* in ms */
u8
bss_index
;
/* The host link id for the AP's global queue */
u8
global_hlid
;
/* The host link id for the AP's broadcast queue */
u8
broadcast_hlid
;
__le16
beacon_interval
;
/* in TBTTs */
__le32
basic_rate_set
;
__le32
local_rates
;
/* local supported rates */
u8
dtim_interval
;
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
padding_1
[
5
];
}
__packed
ap
;
};
}
__packed
;
struct
wl12xx_cmd_role_stop
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
disc_type
;
/* only STA and P2P_CLI */
__le16
reason
;
/* only STA and P2P_CLI */
}
__packed
;
struct
cmd_enabledisable_path
{
...
...
@@ -287,8 +380,9 @@ enum wl1271_cmd_ps_mode {
struct
wl1271_cmd_ps_params
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
ps_mode
;
/* STATION_* */
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
/* HW encryption keys */
...
...
@@ -301,6 +395,12 @@ enum wl1271_cmd_key_action {
MAX_KEY_ACTION
=
0xffff
,
};
enum
wl1271_cmd_lid_key_type
{
UNICAST_LID_TYPE
=
0
,
BROADCAST_LID_TYPE
=
1
,
WEP_DEFAULT_LID_TYPE
=
2
};
enum
wl1271_cmd_key_type
{
KEY_NONE
=
0
,
KEY_WEP
=
1
,
...
...
@@ -309,44 +409,7 @@ enum wl1271_cmd_key_type {
KEY_GEM
=
4
,
};
/* FIXME: Add description for key-types */
struct
wl1271_cmd_set_sta_keys
{
struct
wl1271_cmd_header
header
;
/* Ignored for default WEP key */
u8
addr
[
ETH_ALEN
];
/* key_action_e */
__le16
key_action
;
__le16
reserved_1
;
/* key size in bytes */
u8
key_size
;
/* key_type_e */
u8
key_type
;
u8
ssid_profile
;
/*
* TKIP, AES: frame's key id field.
* For WEP default key: key id;
*/
u8
id
;
u8
reserved_2
[
6
];
u8
key
[
MAX_KEY_SIZE
];
__le16
ac_seq_num16
[
NUM_ACCESS_CATEGORIES_COPY
];
__le32
ac_seq_num32
[
NUM_ACCESS_CATEGORIES_COPY
];
}
__packed
;
enum
wl1271_cmd_lid_key_type
{
UNICAST_LID_TYPE
=
0
,
BROADCAST_LID_TYPE
=
1
,
WEP_DEFAULT_LID_TYPE
=
2
};
struct
wl1271_cmd_set_ap_keys
{
struct
wl1271_cmd_set_keys
{
struct
wl1271_cmd_header
header
;
/*
...
...
@@ -496,69 +559,39 @@ enum wl1271_disconnect_type {
DISCONNECT_DISASSOC
};
struct
wl1271_cmd_disconnect
{
struct
wl1271_cmd_header
header
;
__le32
rx_config_options
;
__le32
rx_filter_options
;
__le16
reason
;
u8
type
;
u8
padding
;
}
__packed
;
#define WL1271_CMD_STA_STATE_CONNECTED 1
struct
wl12
71_cmd_set_sta
_state
{
struct
wl12
xx_cmd_set_peer
_state
{
struct
wl1271_cmd_header
header
;
u8
hlid
;
u8
state
;
u8
padding
[
3
];
u8
padding
[
2
];
}
__packed
;
enum
wl1271_ssid_type
{
SSID_TYPE_PUBLIC
=
0
,
SSID_TYPE_HIDDEN
=
1
struct
wl12xx_cmd_roc
{
struct
wl1271_cmd_header
header
;
u8
role_id
;
u8
channel
;
u8
band
;
u8
padding
;
};
struct
wl12
71_cmd_bss_start
{
struct
wl12
xx_cmd_croc
{
struct
wl1271_cmd_header
header
;
/* wl1271_ssid_type */
u8
ssid_type
;
u8
ssid_len
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
padding_1
[
2
];
/* Basic rate set */
__le32
basic_rate_set
;
/* Aging period in seconds*/
__le16
aging_period
;
u8
role_id
;
u8
padding
[
3
];
};
/*
* This field specifies the time between target beacon
* transmission times (TBTTs), in time units (TUs).
* Valid values are 1 to 1024.
*/
__le16
beacon_interval
;
u8
bssid
[
ETH_ALEN
];
u8
bss_index
;
/* Radio band */
u8
band
;
u8
channel
;
/* The host link id for the AP's global queue */
u8
global_hlid
;
/* The host link id for the AP's broadcast queue */
u8
broadcast_hlid
;
/* DTIM count */
u8
dtim_interval
;
/* Beacon expiry time in ms */
u8
beacon_expiry
;
u8
padding_2
[
3
];
}
__packed
;
enum
wl12xx_ssid_type
{
WL12XX_SSID_TYPE_PUBLIC
=
0
,
WL12XX_SSID_TYPE_HIDDEN
=
1
,
WL12XX_SSID_TYPE_ANY
=
2
,
};
struct
wl12
71_cmd_add_sta
{
struct
wl12
xx_cmd_add_peer
{
struct
wl1271_cmd_header
header
;
u8
addr
[
ETH_ALEN
];
...
...
@@ -572,7 +605,7 @@ struct wl1271_cmd_add_sta {
u8
padding1
;
}
__packed
;
struct
wl12
71_cmd_remove_sta
{
struct
wl12
xx_cmd_remove_peer
{
struct
wl1271_cmd_header
header
;
u8
hlid
;
...
...
drivers/net/wireless/wl12xx/conf.h
浏览文件 @
e0a8c583
...
...
@@ -99,40 +99,75 @@ enum {
enum
{
/*
* PER threshold in PPM of the BT voice
* Configure the min and max time BT gains the antenna
* in WLAN / BT master basic rate
*
* Range: 0 -
10000000
* Range: 0 -
255 (ms)
*/
CONF_SG_BT_PER_THRESHOLD
=
0
,
CONF_SG_ACL_BT_MASTER_MIN_BR
=
0
,
CONF_SG_ACL_BT_MASTER_MAX_BR
,
/*
*
Number of consequent RX_ACTIVE activities to override BT voice
*
frames to ensure WLAN connection
*
Configure the min and max time BT gains the antenna
*
in WLAN / BT slave basic rate
*
* Range: 0 -
100
* Range: 0 -
255 (ms)
*/
CONF_SG_HV3_MAX_OVERRIDE
,
CONF_SG_ACL_BT_SLAVE_MIN_BR
,
CONF_SG_ACL_BT_SLAVE_MAX_BR
,
/*
* Defines the PER threshold of the BT voice
* Configure the min and max time BT gains the antenna
* in WLAN / BT master EDR
*
* Range: 0 -
65000
* Range: 0 -
255 (ms)
*/
CONF_SG_BT_NFS_SAMPLE_INTERVAL
,
CONF_SG_ACL_BT_MASTER_MIN_EDR
,
CONF_SG_ACL_BT_MASTER_MAX_EDR
,
/*
* Defines the load ratio of BT
* Configure the min and max time BT gains the antenna
* in WLAN / BT slave EDR
*
* Range: 0 -
100 (%
)
* Range: 0 -
255 (ms
)
*/
CONF_SG_BT_LOAD_RATIO
,
CONF_SG_ACL_BT_SLAVE_MIN_EDR
,
CONF_SG_ACL_BT_SLAVE_MAX_EDR
,
/*
* Defines whether the SG will force WLAN host to enter/exit PSM
* The maximum time WLAN can gain the antenna
* in WLAN PSM / BT master/slave BR
*
* Range:
1 - SG can force, 0 - host handles PSM
* Range:
0 - 255 (ms)
*/
CONF_SG_AUTO_PS_MODE
,
CONF_SG_ACL_WLAN_PS_MASTER_BR
,
CONF_SG_ACL_WLAN_PS_SLAVE_BR
,
/*
* The maximum time WLAN can gain the antenna
* in WLAN PSM / BT master/slave EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_ACL_WLAN_PS_MASTER_EDR
,
CONF_SG_ACL_WLAN_PS_SLAVE_EDR
,
/* TODO: explain these values */
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR
,
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR
,
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR
,
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR
,
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR
,
CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR
,
CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR
,
CONF_SG_ACL_PASSIVE_SCAN_BT_BR
,
CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR
,
CONF_SG_ACL_PASSIVE_SCAN_BT_EDR
,
CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR
,
/*
* Compensation percentage of probe requests when scan initiated
...
...
@@ -151,102 +186,70 @@ enum {
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3
,
/*
* Defines antenna configuration (single/dual antenna)
*
* Range: 0 - single antenna, 1 - dual antenna
*/
CONF_SG_ANTENNA_CONFIGURATION
,
/*
* The threshold (percent) of max consequtive beacon misses before
* increasing priority of beacon reception.
*
* Range: 0 - 100 (%)
*/
CONF_SG_BEACON_MISS_PERCENT
,
/*
* The rate threshold below which receiving a data frame from the AP
* will increase the priority of the data frame above BT traffic.
*
* Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54
*/
CONF_SG_RATE_ADAPT_THRESH
,
/*
* Not used currently.
* Compensation percentage of WLAN active scan window if initiated
* during BT A2DP
*
* Range: 0
* Range: 0
- 1000 (%)
*/
CONF_SG_
RATE_ADAPT_SNR
,
CONF_SG_
ACTIVE_SCAN_DURATION_FACTOR_A2DP
,
/*
* Co
nfigure the min and max time BT gains the antenna
*
in WLAN PSM / BT master basic rate
* Co
mpensation percentage of WLAN passive scan window if initiated
*
during BT A2DP BR
*
* Range: 0 -
255 (ms
)
* Range: 0 -
1000 (%
)
*/
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR
,
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR
,
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR
,
/*
*
The time after it expires no new WLAN trigger frame is trasmit
ted
*
in WLAN PSM / BT master basic rate
*
Compensation percentage of WLAN passive scan window if initia
ted
*
during BT A2DP EDR
*
* Range: 0 -
255 (ms
)
* Range: 0 -
1000 (%
)
*/
CONF_SG_
WLAN_PS_MAX_BT_ACL_MASTER_B
R
,
CONF_SG_
PASSIVE_SCAN_DURATION_FACTOR_A2DP_ED
R
,
/*
* Co
nfigure the min and max time BT gains the antenna
*
in WLAN PSM / BT slave basic rat
e
* Co
mpensation percentage of WLAN passive scan window if initiated
*
during BT voic
e
*
* Range: 0 -
255 (ms
)
* Range: 0 -
1000 (%
)
*/
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR
,
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR
,
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
,
/*
* The time after it expires no new WLAN trigger frame is trasmitted
* in WLAN PSM / BT slave basic rate
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR
,
/* TODO: explain these values */
CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN
,
CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN
,
CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN PSM / BT master EDR
* Defines whether the SG will force WLAN host to enter/exit PSM
*
* Range:
0 - 255 (ms)
* Range:
1 - SG can force, 0 - host handles PSM
*/
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR
,
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR
,
CONF_SG_STA_FORCE_PS_IN_BT_SCO
,
/*
* The time after it expires no new WLAN trigger frame is trasmitted
* in WLAN PSM / BT master EDR
* Defines antenna configuration (single/dual antenna)
*
* Range: 0 -
255 (ms)
* Range: 0 -
single antenna, 1 - dual antenna
*/
CONF_SG_
WLAN_PS_MAX_BT_ACL_MASTER_EDR
,
CONF_SG_
ANTENNA_CONFIGURATION
,
/*
*
Configure the min and max time BT gains the antenna
* in
WLAN PSM / BT slave EDR
*
The threshold (percent) of max consecutive beacon misses before
* in
creasing priority of beacon reception.
*
* Range: 0 -
255 (ms
)
* Range: 0 -
100 (%
)
*/
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR
,
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR
,
CONF_SG_BEACON_MISS_PERCENT
,
/*
* The time after it expires no new WLAN trigger frame is trasmitted
* in WLAN PSM / BT slave EDR
* Protection time of the DHCP procedure.
*
* Range: 0 -
255
(ms)
* Range: 0 -
100000
(ms)
*/
CONF_SG_
WLAN_PS_MAX_BT_ACL_SLAVE_EDR
,
CONF_SG_
DHCP_TIME
,
/*
* RX guard time before the beginning of a new BT voice frame during
...
...
@@ -273,166 +276,59 @@ enum {
*/
CONF_SG_ADAPTIVE_RXT_TXT
,
/*
* The used WLAN legacy service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_PS_POLL_TIMEOUT
,
/*
* The used WLAN UPSD service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_UPSD_TIMEOUT
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN Active / BT master EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR
,
CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR
,
/*
* The maximum time WLAN can gain the antenna for
* in WLAN Active / BT master EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN Active / BT slave EDR
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR
,
CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR
,
/* TODO: explain this value */
CONF_SG_GENERAL_USAGE_BIT_MAP
,
/*
* The maximum time WLAN can gain the antenna for
* in WLAN Active / BT slave EDR
* Number of consecutive BT voice frames not interrupted by WLAN
*
* Range: 0 -
255 (ms)
* Range: 0 -
100
*/
CONF_SG_
WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR
,
CONF_SG_
HV3_MAX_SERVED
,
/*
* Configure the min and max time BT gains the antenna
* in WLAN Active / BT basic rate
* The used WLAN legacy service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR
,
CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR
,
CONF_SG_PS_POLL_TIMEOUT
,
/*
* The maximum time WLAN can gain the antenna for
* in WLAN Active / BT basic rate
* The used WLAN UPSD service period during active BT ACL link
*
* Range: 0 - 255 (ms)
*/
CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR
,
/*
* Compensation percentage of WLAN passive scan window if initiated
* during BT voice
*
* Range: 0 - 1000 (%)
*/
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
,
/*
* Compensation percentage of WLAN passive scan window if initiated
* during BT A2DP
*
* Range: 0 - 1000 (%)
*/
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP
,
/*
* Fixed time ensured for BT traffic to gain the antenna during WLAN
* passive scan.
*
* Range: 0 - 1000 ms
*/
CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME
,
/*
* Fixed time ensured for WLAN traffic to gain the antenna during WLAN
* passive scan.
*
* Range: 0 - 1000 ms
*/
CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME
,
CONF_SG_UPSD_TIMEOUT
,
/*
* Number of consequent BT voice frames not interrupted by WLAN
*
* Range: 0 - 100
*/
CONF_SG_HV3_MAX_SERVED
,
CONF_SG_CONSECUTIVE_CTS_THRESHOLD
,
CONF_SG_STA_RX_WINDOW_AFTER_DTIM
,
CONF_SG_STA_CONNECTION_PROTECTION_TIME
,
/*
* Protection time of the DHCP procedure.
*
* Range: 0 - 100000 (ms)
*/
CONF_SG_DHCP_TIME
,
/* AP params */
CONF_AP_BEACON_MISS_TX
,
CONF_AP_RX_WINDOW_AFTER_BEACON
,
CONF_AP_BEACON_WINDOW_INTERVAL
,
CONF_AP_CONNECTION_PROTECTION_TIME
,
CONF_AP_BT_ACL_VAL_BT_SERVE_TIME
,
CONF_AP_BT_ACL_VAL_WL_SERVE_TIME
,
/*
* Compensation percentage of WLAN active scan window if initiated
* during BT A2DP
*
* Range: 0 - 1000 (%)
*/
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
,
CONF_SG_TEMP_PARAM_1
,
CONF_SG_TEMP_PARAM_2
,
CONF_SG_TEMP_PARAM_3
,
CONF_SG_TEMP_PARAM_4
,
CONF_SG_TEMP_PARAM_5
,
/*
* 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_MAX
,
CONF_SG_PARAMS_ALL
=
0xff
};
struct
conf_sg_settings
{
u32
sta_params
[
CONF_SG_STA_PARAMS_MAX
];
u32
ap_params
[
CONF_SG_AP_PARAMS_MAX
];
u32
params
[
CONF_SG_PARAMS_MAX
];
u8
state
;
};
...
...
@@ -545,6 +441,11 @@ struct conf_rx_settings {
CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
CONF_HW_BIT_RATE_54MBPS)
#define CONF_TX_MCS_RATES (CONF_HW_BIT_RATE_MCS_0 | \
CONF_HW_BIT_RATE_MCS_1 | CONF_HW_BIT_RATE_MCS_2 | \
CONF_HW_BIT_RATE_MCS_3 | CONF_HW_BIT_RATE_MCS_4 | \
CONF_HW_BIT_RATE_MCS_5 | CONF_HW_BIT_RATE_MCS_6 | \
CONF_HW_BIT_RATE_MCS_7)
/*
* Default rates for management traffic when operating in AP mode. This
...
...
@@ -661,6 +562,9 @@ struct conf_tx_ac_category {
#define CONF_TX_MAX_TID_COUNT 8
/* Allow TX BA on all TIDs but 6,7. These are currently reserved in the FW */
#define CONF_TX_BA_ENABLED_TID_BITMAP 0x3F
enum
{
CONF_CHANNEL_TYPE_DCF
=
0
,
/* DC/LEGACY*/
CONF_CHANNEL_TYPE_EDCF
=
1
,
/* EDCA*/
...
...
@@ -913,7 +817,7 @@ struct conf_conn_settings {
struct
conf_bcn_filt_rule
bcn_filt_ie
[
CONF_MAX_BCN_FILT_IE_COUNT
];
/*
* The number of conse
q
utive beacons to lose, before the firmware
* The number of conse
c
utive beacons to lose, before the firmware
* becomes out of synch.
*
* Range: u32
...
...
@@ -951,7 +855,7 @@ struct conf_conn_settings {
u8
rx_broadcast_in_ps
;
/*
* Conse
q
utive PS Poll failures before sending event to driver
* Conse
c
utive PS Poll failures before sending event to driver
*
* Range: u8
*/
...
...
@@ -1199,8 +1103,12 @@ struct conf_rf_settings {
};
struct
conf_ht_setting
{
u16
tx_ba_win_size
;
u8
rx_ba_win_size
;
u8
tx_ba_win_size
;
u16
inactivity_timeout
;
/* bitmap of enabled TIDs for TX BA sessions */
u8
tx_ba_tid_bitmap
;
};
struct
conf_memory_settings
{
...
...
@@ -1309,6 +1217,25 @@ struct conf_fwlog {
u8
threshold
;
};
#define ACX_RATE_MGMT_NUM_OF_RATES 13
struct
conf_rate_policy_settings
{
u16
rate_retry_score
;
u16
per_add
;
u16
per_th1
;
u16
per_th2
;
u16
max_per
;
u8
inverse_curiosity_factor
;
u8
tx_fail_low_th
;
u8
tx_fail_high_th
;
u8
per_alpha_shift
;
u8
per_add_shift
;
u8
per_beta1_shift
;
u8
per_beta2_shift
;
u8
rate_check_up
;
u8
rate_check_down
;
u8
rate_retry_policy
[
ACX_RATE_MGMT_NUM_OF_RATES
];
};
struct
conf_drv_settings
{
struct
conf_sg_settings
sg
;
struct
conf_rx_settings
rx
;
...
...
@@ -1326,6 +1253,7 @@ struct conf_drv_settings {
struct
conf_fm_coex
fm_coex
;
struct
conf_rx_streaming_settings
rx_streaming
;
struct
conf_fwlog
fwlog
;
struct
conf_rate_policy_settings
rate
;
u8
hci_io_ds
;
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
浏览文件 @
e0a8c583
...
...
@@ -339,10 +339,11 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
#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
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
[
1
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
[
2
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
[
3
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_blocks
);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
1
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
2
]);
DRIVER_STATE_PRINT_INT
(
tx_allocated_pkts
[
3
]);
DRIVER_STATE_PRINT_INT
(
tx_frames_cnt
);
DRIVER_STATE_PRINT_LHEX
(
tx_frames_map
[
0
]);
DRIVER_STATE_PRINT_INT
(
tx_queue_count
[
0
]);
...
...
@@ -352,10 +353,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
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_blocks_freed
);
DRIVER_STATE_PRINT_INT
(
tx_security_last_seq_lsb
);
DRIVER_STATE_PRINT_INT
(
rx_counter
);
DRIVER_STATE_PRINT_INT
(
session_counter
);
...
...
@@ -369,9 +367,6 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
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
);
...
...
drivers/net/wireless/wl12xx/event.c
浏览文件 @
e0a8c583
...
...
@@ -285,13 +285,13 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
if
((
vector
&
BA_SESSION_RX_CONSTRAINT_EVENT_ID
)
&&
!
is_ap
)
{
wl1271_debug
(
DEBUG_EVENT
,
"BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
"ba_allowed = 0x%x"
,
mbox
->
ba_allowed
);
"ba_allowed = 0x%x"
,
mbox
->
rx_
ba_allowed
);
if
(
wl
->
vif
)
wl1271_stop_ba_event
(
wl
,
mbox
->
ba_allowed
);
wl1271_stop_ba_event
(
wl
,
mbox
->
rx_
ba_allowed
);
}
if
((
vector
&
DUMMY_PACKET_EVENT_ID
)
&&
!
is_ap
)
{
if
((
vector
&
DUMMY_PACKET_EVENT_ID
))
{
wl1271_debug
(
DEBUG_EVENT
,
"DUMMY_PACKET_ID_EVENT_ID"
);
if
(
wl
->
vif
)
wl1271_tx_dummy_packet
(
wl
);
...
...
drivers/net/wireless/wl12xx/event.h
浏览文件 @
e0a8c583
...
...
@@ -49,32 +49,27 @@ enum {
MEASUREMENT_START_EVENT_ID
=
BIT
(
8
),
MEASUREMENT_COMPLETE_EVENT_ID
=
BIT
(
9
),
SCAN_COMPLETE_EVENT_ID
=
BIT
(
10
),
SCHEDULED_SCAN_COMPLETE_EVENT_ID
=
BIT
(
11
),
WFD_DISCOVERY_COMPLETE_EVENT_ID
=
BIT
(
11
),
AP_DISCOVERY_COMPLETE_EVENT_ID
=
BIT
(
12
),
PS_REPORT_EVENT_ID
=
BIT
(
13
),
PSPOLL_DELIVERY_FAILURE_EVENT_ID
=
BIT
(
14
),
DISCONNECT_EVENT_COMPLETE_ID
=
BIT
(
15
),
JOIN_EVENT_COMPLETE_ID
=
BIT
(
16
),
/* BIT(16) is reserved */
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
),
/* STA: dummy paket for dynamic mem blocks */
DUMMY_PACKET_EVENT_ID
=
BIT
(
21
),
/* AP: STA remove complete */
STA_REMOVE_COMPLETE_EVENT_ID
=
BIT
(
21
),
DUMMY_PACKET_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
),
CHANGE_AUTO_MODE_TIMEOUT_EVENT_ID
=
BIT
(
23
),
SOFT_GEMINI_AVALANCHE_EVENT_ID
=
BIT
(
24
),
PLT_RX_CALIBRATION_COMPLETE_EVENT_ID
=
BIT
(
25
),
DBG_EVENT_ID
=
BIT
(
26
),
HEALTH_CHECK_REPLY
_EVENT_ID
=
BIT
(
27
),
INACTIVE_STA_EVENT_ID
=
BIT
(
26
),
PEER_REMOVE_COMPLETE
_EVENT_ID
=
BIT
(
27
),
PERIODIC_SCAN_COMPLETE_EVENT_ID
=
BIT
(
28
),
PERIODIC_SCAN_REPORT_EVENT_ID
=
BIT
(
29
),
BA_SESSION_RX_CONSTRAINT_EVENT_ID
=
BIT
(
30
),
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID
=
BIT
(
31
),
EVENT_MBOX_ALL_EVENT_ID
=
0x7fffffff
,
};
...
...
@@ -83,15 +78,6 @@ enum {
EVENT_ENTER_POWER_SAVE_SUCCESS
,
};
struct
event_debug_report
{
u8
debug_event_id
;
u8
num_params
;
__le16
pad
;
__le32
report_1
;
__le32
report_2
;
__le32
report_3
;
}
__packed
;
#define NUM_OF_RSSI_SNR_TRIGGERS 8
struct
event_mailbox
{
...
...
@@ -100,49 +86,45 @@ struct event_mailbox {
__le32
reserved_1
;
__le32
reserved_2
;
u8
dbg_event_id
;
u8
num_relevant_params
;
__le16
reserved_3
;
__le32
event_report_p1
;
__le32
event_report_p2
;
__le32
event_report_p3
;
u8
number_of_scan_results
;
u8
scan_tag
;
u8
reserved_4
[
2
]
;
__le32
compl_scheduled_scan_status
;
u8
completed_scan_status
;
u8
reserved_3
;
__le16
scheduled_scan_attended_channels
;
u8
soft_gemini_sense_info
;
u8
soft_gemini_protective_info
;
s8
rssi_snr_trigger_metric
[
NUM_OF_RSSI_SNR_TRIGGERS
];
u8
channel_switch_status
;
u8
scheduled_scan_status
;
u8
ps_status
;
/* tuned channel (roc) */
u8
roc_channel
;
/* AP FW only */
u8
hlid_removed
;
__le16
hlid_removed_bitmap
;
/*
a bitmap of hlids for stations that have been inactive too long
*/
/*
bitmap of aged stations (by HLID)
*/
__le16
sta_aging_status
;
/*
a bitmap of hlids for stations which didn't respond to TX
*/
/*
bitmap of stations (by HLID) which exceeded max tx retries
*/
__le16
sta_tx_retry_exceeded
;
/*
* Bitmap, Each bit set represents the Role ID for which this constraint
* is set. Range: 0 - FF, FF means ANY role
*/
u8
ba_role_id
;
/*
* Bitmap, Each bit set represents the Link ID for which this constraint
* is set. Not applicable if ba_role_id is set to ANY role (FF).
* Range: 0 - FFFF, FFFF means ANY link in that role
*/
u8
ba_link_id
;
u8
ba_allowed
;
u8
reserved_5
[
21
];
/* discovery completed results */
u8
discovery_tag
;
u8
number_of_preq_results
;
u8
number_of_prsp_results
;
u8
reserved_5
;
/* rx ba constraint */
u8
role_id
;
/* 0xFF means any role. */
u8
rx_ba_allowed
;
u8
reserved_6
[
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
];
}
__packed
;
int
wl1271_event_unmask
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/init.c
浏览文件 @
e0a8c583
...
...
@@ -39,13 +39,13 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl)
/* send empty templates for fw memory reservation */
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_CFG_PROBE_REQ_2_4
,
NULL
,
WL1271_CMD_TEMPL_
MAX
_SIZE
,
WL1271_CMD_TEMPL_
DFLT
_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_
MAX
_SIZE
,
0
,
NULL
,
WL1271_CMD_TEMPL_
DFLT
_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -70,15 +70,13 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_PROBE_RESPONSE
,
NULL
,
sizeof
(
struct
wl12xx_probe_resp_template
),
WL1271_CMD_TEMPL_DFLT_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_BEACON
,
NULL
,
sizeof
(
struct
wl12xx_beacon_template
),
WL1271_CMD_TEMPL_DFLT_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -92,7 +90,7 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl)
for
(
i
=
0
;
i
<
CMD_TEMPL_KLV_IDX_MAX
;
i
++
)
{
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_KLV
,
NULL
,
WL1271_CMD_TEMPL_
MAX
_SIZE
,
i
,
WL1271_CMD_TEMPL_
DFLT
_SIZE
,
i
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -191,15 +189,13 @@ static int wl1271_ap_init_templates_config(struct wl1271 *wl)
* reserve memory for later.
*/
ret
=
wl1271_cmd_template_set
(
wl
,
CMD_TEMPL_AP_PROBE_RESPONSE
,
NULL
,
sizeof
(
struct
wl12xx_probe_resp_template
),
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
,
sizeof
(
struct
wl12xx_beacon_template
),
WL1271_CMD_TEMPL_MAX_SIZE
,
0
,
WL1271_RATE_AUTOMATIC
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -227,7 +223,7 @@ static int wl1271_ap_init_templates_config(struct wl1271 *wl)
return
0
;
}
static
int
wl12
71_init_rx_config
(
struct
wl1271
*
wl
,
u32
config
,
u32
filter
)
static
int
wl12
xx_init_rx_config
(
struct
wl1271
*
wl
)
{
int
ret
;
...
...
@@ -235,10 +231,6 @@ static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter)
if
(
ret
<
0
)
return
ret
;
ret
=
wl1271_acx_rx_config
(
wl
,
config
,
filter
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
...
...
@@ -285,10 +277,7 @@ int wl1271_init_pta(struct wl1271 *wl)
{
int
ret
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
ret
=
wl1271_acx_ap_sg_cfg
(
wl
);
else
ret
=
wl1271_acx_sta_sg_cfg
(
wl
);
ret
=
wl12xx_acx_sg_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -392,7 +381,7 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl12
71_acx_sta
_mem_cfg
(
wl
);
ret
=
wl12
xx_acx
_mem_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -408,12 +397,6 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
{
int
ret
,
i
;
ret
=
wl1271_cmd_set_sta_default_wep_key
(
wl
,
wl
->
default_key
);
if
(
ret
<
0
)
{
wl1271_warning
(
"couldn't set default key"
);
return
ret
;
}
/* disable all keep-alive templates */
for
(
i
=
0
;
i
<
CMD_TEMPL_KLV_IDX_MAX
;
i
++
)
{
ret
=
wl1271_acx_keep_alive_config
(
wl
,
i
,
...
...
@@ -451,7 +434,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
return
ret
;
ret
=
wl12
71_acx_ap
_mem_cfg
(
wl
);
ret
=
wl12
xx_acx
_mem_cfg
(
wl
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -483,7 +466,7 @@ int wl1271_ap_init_templates(struct wl1271 *wl)
* when operating as AP we want to receive external beacons for
* configuring ERP protection.
*/
ret
=
wl1271_acx_
set_ap_beacon_filter
(
wl
,
false
);
ret
=
wl1271_acx_
beacon_filter_opt
(
wl
,
false
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -532,6 +515,9 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
else
supported_rates
=
CONF_TX_AP_ENABLED_RATES
;
/* unconditionally enable HT rates */
supported_rates
|=
CONF_TX_MCS_RATES
;
/* configure unicast TX rate classes */
for
(
i
=
0
;
i
<
wl
->
conf
.
tx
.
ac_conf_count
;
i
++
)
{
rc
.
enabled_rates
=
supported_rates
;
...
...
@@ -546,41 +532,24 @@ int wl1271_init_ap_rates(struct wl1271 *wl)
return
0
;
}
static
void
wl1271_check_ba_support
(
struct
wl1271
*
wl
)
{
/* validate FW cose ver x.x.x.50-60.x */
if
((
wl
->
chip
.
fw_ver
[
3
]
>=
WL12XX_BA_SUPPORT_FW_COST_VER2_START
)
&&
(
wl
->
chip
.
fw_ver
[
3
]
<
WL12XX_BA_SUPPORT_FW_COST_VER2_END
))
{
wl
->
ba_support
=
true
;
return
;
}
wl
->
ba_support
=
false
;
}
static
int
wl1271_set_ba_policies
(
struct
wl1271
*
wl
)
{
u8
tid_index
;
int
ret
=
0
;
/* Reset the BA RX indicators */
wl
->
ba_rx_bitmap
=
0
;
wl
->
ba_allowed
=
true
;
wl
->
ba_rx_session_count
=
0
;
/* validate that FW support BA */
wl1271_check_ba_support
(
wl
);
/* BA is supported in STA/AP modes */
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
&&
wl
->
bss_type
!=
BSS_TYPE_STA_BSS
)
{
wl
->
ba_support
=
false
;
return
0
;
}
if
(
wl
->
ba_support
)
/* 802.11n initiator BA session setting */
for
(
tid_index
=
0
;
tid_index
<
CONF_TX_MAX_TID_COUNT
;
++
tid_index
)
{
ret
=
wl1271_acx_set_ba_session
(
wl
,
WLAN_BACK_INITIATOR
,
tid_index
,
true
);
if
(
ret
<
0
)
break
;
}
wl
->
ba_support
=
true
;
return
ret
;
/* 802.11n initiator BA session setting */
return
wl12xx_acx_set_ba_initiator_policy
(
wl
);
}
int
wl1271_chip_specific_init
(
struct
wl1271
*
wl
)
...
...
@@ -650,11 +619,7 @@ int wl1271_hw_init(struct wl1271 *wl)
return
ret
;
/* RX config */
ret
=
wl1271_init_rx_config
(
wl
,
RX_CFG_PROMISCUOUS
|
RX_CFG_TSF
,
RX_FILTER_OPTION_DEF
);
/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
RX_FILTER_OPTION_FILTER_ALL); */
ret
=
wl12xx_init_rx_config
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
@@ -733,6 +698,10 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
ret
=
wl12xx_acx_set_rate_mgmt_params
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
/* Configure initiator BA sessions policies */
ret
=
wl1271_set_ba_policies
(
wl
);
if
(
ret
<
0
)
...
...
drivers/net/wireless/wl12xx/io.h
浏览文件 @
e0a8c583
...
...
@@ -186,6 +186,5 @@ int wl1271_free_hw(struct wl1271 *wl);
irqreturn_t
wl1271_irq
(
int
irq
,
void
*
data
);
bool
wl1271_set_block_size
(
struct
wl1271
*
wl
);
int
wl1271_tx_dummy_packet
(
struct
wl1271
*
wl
);
void
wl1271_configure_filters
(
struct
wl1271
*
wl
,
unsigned
int
filters
);
#endif
drivers/net/wireless/wl12xx/main.c
浏览文件 @
e0a8c583
...
...
@@ -52,110 +52,67 @@
static
struct
conf_drv_settings
default_conf
=
{
.
sg
=
{
.
sta_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
]
=
200
,
[
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
]
=
12
,
[
CONF_SG_RATE_ADAPT_SNR
]
=
0
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR
]
=
10
,
[
CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR
]
=
30
,
[
CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR
]
=
8
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR
]
=
20
,
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR
]
=
50
,
/* Note: with UPSD, this should be 4 */
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR
]
=
8
,
[
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
]
=
20
,
/* Note: with UPDS, this should be 15 */
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR
]
=
8
,
/* Note: with UPDS, this should be 50 */
[
CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR
]
=
40
,
/* Note: with UPDS, this should be 10 */
[
CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR
]
=
20
,
[
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
,
},
.
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
,
.
params
=
{
[
CONF_SG_ACL_BT_MASTER_MIN_BR
]
=
10
,
[
CONF_SG_ACL_BT_MASTER_MAX_BR
]
=
180
,
[
CONF_SG_ACL_BT_SLAVE_MIN_BR
]
=
10
,
[
CONF_SG_ACL_BT_SLAVE_MAX_BR
]
=
180
,
[
CONF_SG_ACL_BT_MASTER_MIN_EDR
]
=
10
,
[
CONF_SG_ACL_BT_MASTER_MAX_EDR
]
=
80
,
[
CONF_SG_ACL_BT_SLAVE_MIN_EDR
]
=
10
,
[
CONF_SG_ACL_BT_SLAVE_MAX_EDR
]
=
80
,
[
CONF_SG_ACL_WLAN_PS_MASTER_BR
]
=
8
,
[
CONF_SG_ACL_WLAN_PS_SLAVE_BR
]
=
8
,
[
CONF_SG_ACL_WLAN_PS_MASTER_EDR
]
=
20
,
[
CONF_SG_ACL_WLAN_PS_SLAVE_EDR
]
=
20
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR
]
=
20
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR
]
=
35
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR
]
=
16
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR
]
=
35
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR
]
=
32
,
[
CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR
]
=
50
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR
]
=
28
,
[
CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR
]
=
50
,
[
CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR
]
=
10
,
[
CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR
]
=
20
,
[
CONF_SG_ACL_PASSIVE_SCAN_BT_BR
]
=
75
,
[
CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR
]
=
15
,
[
CONF_SG_ACL_PASSIVE_SCAN_BT_EDR
]
=
27
,
[
CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR
]
=
17
,
/* active scan params */
[
CONF_SG_AUTO_SCAN_PROBE_REQ
]
=
170
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3
]
=
50
,
[
CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP
]
=
100
,
/* passive scan params */
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR
]
=
800
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR
]
=
200
,
[
CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3
]
=
200
,
/* passive scan in dual antenna params */
[
CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN
]
=
0
,
[
CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN
]
=
0
,
[
CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN
]
=
0
,
/* general params */
[
CONF_SG_STA_FORCE_PS_IN_BT_SCO
]
=
1
,
[
CONF_SG_ANTENNA_CONFIGURATION
]
=
0
,
[
CONF_SG_BEACON_MISS_PERCENT
]
=
60
,
[
CONF_SG_DHCP_TIME
]
=
5000
,
[
CONF_SG_RXT
]
=
1200
,
[
CONF_SG_TXT
]
=
1000
,
[
CONF_SG_ADAPTIVE_RXT_TXT
]
=
1
,
[
CONF_SG_GENERAL_USAGE_BIT_MAP
]
=
3
,
[
CONF_SG_HV3_MAX_SERVED
]
=
6
,
[
CONF_SG_PS_POLL_TIMEOUT
]
=
10
,
[
CONF_SG_UPSD_TIMEOUT
]
=
10
,
[
CONF_SG_CONSECUTIVE_CTS_THRESHOLD
]
=
2
,
[
CONF_SG_STA_RX_WINDOW_AFTER_DTIM
]
=
5
,
[
CONF_SG_STA_CONNECTION_PROTECTION_TIME
]
=
30
,
/* AP params */
[
CONF_AP_BEACON_MISS_TX
]
=
3
,
[
CONF_AP_RX_WINDOW_AFTER_BEACON
]
=
10
,
[
CONF_AP_BEACON_WINDOW_INTERVAL
]
=
2
,
[
CONF_AP_CONNECTION_PROTECTION_TIME
]
=
0
,
[
CONF_AP_BT_ACL_VAL_BT_SERVE_TIME
]
=
25
,
[
CONF_AP_BT_ACL_VAL_WL_SERVE_TIME
]
=
25
,
},
.
state
=
CONF_SG_PROTECTIVE
,
},
...
...
@@ -329,8 +286,10 @@ static struct conf_drv_settings default_conf = {
},
},
.
ht
=
{
.
rx_ba_win_size
=
8
,
.
tx_ba_win_size
=
64
,
.
inactivity_timeout
=
10000
,
.
tx_ba_tid_bitmap
=
CONF_TX_BA_ENABLED_TID_BITMAP
,
},
.
mem_wl127x
=
{
.
num_stations
=
1
,
...
...
@@ -379,6 +338,27 @@ static struct conf_drv_settings default_conf = {
.
threshold
=
0
,
},
.
hci_io_ds
=
HCI_IO_DS_6MA
,
.
rate
=
{
.
rate_retry_score
=
32000
,
.
per_add
=
8192
,
.
per_th1
=
2048
,
.
per_th2
=
4096
,
.
max_per
=
8100
,
.
inverse_curiosity_factor
=
5
,
.
tx_fail_low_th
=
4
,
.
tx_fail_high_th
=
10
,
.
per_alpha_shift
=
4
,
.
per_add_shift
=
13
,
.
per_beta1_shift
=
10
,
.
per_beta2_shift
=
8
,
.
rate_check_up
=
2
,
.
rate_check_down
=
12
,
.
rate_retry_policy
=
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
},
},
};
static
char
*
fwlog_param
;
...
...
@@ -415,10 +395,12 @@ static int wl1271_check_operstate(struct wl1271 *wl, unsigned char operstate)
if
(
test_and_set_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
))
return
0
;
ret
=
wl12
71_cmd_set_sta_state
(
wl
);
ret
=
wl12
xx_cmd_set_peer_state
(
wl
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
return
ret
;
wl12xx_croc
(
wl
,
wl
->
role_id
);
wl1271_info
(
"Association completed."
);
return
0
;
}
...
...
@@ -718,7 +700,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
ret
=
wl12
71_acx_sta
_mem_cfg
(
wl
);
ret
=
wl12
xx_acx
_mem_cfg
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
...
...
@@ -773,7 +755,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
return
ret
;
}
static
void
wl12
71_irq_ps_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
,
u8
tx_blk
s
)
static
void
wl12
xx_irq_ps_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
,
u8
tx_pkt
s
)
{
bool
fw_ps
;
...
...
@@ -785,21 +767,35 @@ static void wl1271_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_blks)
/*
* Wake up from high level PS if the STA is asleep with too little
*
block
s in FW or if the STA is awake.
*
packet
s in FW or if the STA is awake.
*/
if
(
!
fw_ps
||
tx_
blks
<
WL1271_PS_STA_MAX_BLOCK
S
)
if
(
!
fw_ps
||
tx_
pkts
<
WL1271_PS_STA_MAX_PACKET
S
)
wl1271_ps_link_end
(
wl
,
hlid
);
/* Start high-level PS if the STA is asleep with enough blocks in FW */
else
if
(
fw_ps
&&
tx_
blks
>=
WL1271_PS_STA_MAX_BLOCK
S
)
else
if
(
fw_ps
&&
tx_
pkts
>=
WL1271_PS_STA_MAX_PACKET
S
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
static
void
wl1271_irq_update_links_status
(
struct
wl1271
*
wl
,
struct
wl1271_fw_ap_status
*
status
)
bool
wl1271_is_active_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
{
int
id
;
/* global/broadcast "stations" are always active */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
true
;
id
=
hlid
-
WL1271_AP_STA_HLID_START
;
return
test_bit
(
id
,
wl
->
ap_hlid_map
);
}
static
void
wl12xx_irq_update_links_status
(
struct
wl1271
*
wl
,
struct
wl12xx_fw_status
*
status
)
{
u32
cur_fw_ps_map
;
u8
hlid
;
u8
hlid
,
cnt
;
/* TODO: also use link_fast_bitmap here */
cur_fw_ps_map
=
le32_to_cpu
(
status
->
link_ps_bitmap
);
if
(
wl
->
ap_fw_ps_map
!=
cur_fw_ps_map
)
{
...
...
@@ -812,45 +808,30 @@ static void wl1271_irq_update_links_status(struct wl1271 *wl,
}
for
(
hlid
=
WL1271_AP_STA_HLID_START
;
hlid
<
AP_MAX_LINKS
;
hlid
++
)
{
u8
cnt
=
status
->
tx_lnk_free_blks
[
hlid
]
-
wl
->
links
[
hlid
].
prev_freed_blks
;
if
(
!
wl1271_is_active_sta
(
wl
,
hlid
))
continue
;
wl
->
links
[
hlid
].
prev_freed_blks
=
status
->
tx_lnk_free_blks
[
hlid
];
wl
->
links
[
hlid
].
allocated_blks
-=
cnt
;
cnt
=
status
->
tx_lnk_free_pkts
[
hlid
]
-
wl
->
links
[
hlid
].
prev_freed_pkts
;
wl1271_irq_ps_regulate_link
(
wl
,
hlid
,
wl
->
links
[
hlid
].
allocated_blks
);
}
}
wl
->
links
[
hlid
].
prev_freed_pkts
=
status
->
tx_lnk_free_pkts
[
hlid
];
wl
->
links
[
hlid
].
allocated_pkts
-=
cnt
;
static
u32
wl1271_tx_allocated_blocks
(
struct
wl1271
*
wl
)
{
int
i
;
u32
total_alloc_blocks
=
0
;
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
total_alloc_blocks
+=
wl
->
tx_allocated_blocks
[
i
];
return
total_alloc_blocks
;
wl12xx_irq_ps_regulate_link
(
wl
,
hlid
,
wl
->
links
[
hlid
].
allocated_pkts
);
}
}
static
void
wl12
71
_fw_status
(
struct
wl1271
*
wl
,
struct
wl12
71_fw_full_status
*
full_
status
)
static
void
wl12
xx
_fw_status
(
struct
wl1271
*
wl
,
struct
wl12
xx_fw_status
*
status
)
{
struct
wl1271_fw_common_status
*
status
=
&
full_status
->
common
;
struct
timespec
ts
;
u32
old_tx_blk_count
=
wl
->
tx_blocks_available
;
u32
freed_blocks
=
0
,
ac_
freed_blocks
;
int
avail
,
freed_blocks
;
int
i
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
wl1271_raw_read
(
wl
,
FW_STATUS_ADDR
,
status
,
sizeof
(
struct
wl1271_fw_ap_status
),
false
);
}
else
{
wl1271_raw_read
(
wl
,
FW_STATUS_ADDR
,
status
,
sizeof
(
struct
wl1271_fw_sta_status
),
false
);
}
wl1271_raw_read
(
wl
,
FW_STATUS_ADDR
,
status
,
sizeof
(
*
status
),
false
);
wl1271_debug
(
DEBUG_IRQ
,
"intr: 0x%x (fw_rx_counter = %d, "
"drv_rx_counter = %d, tx_results_counter = %d)"
,
...
...
@@ -859,42 +840,49 @@ static void wl1271_fw_status(struct wl1271 *wl,
status
->
drv_rx_counter
,
status
->
tx_results_counter
);
/* update number of available TX blocks */
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
ac_freed_blocks
=
le32_to_cpu
(
status
->
tx_released_blks
[
i
])
-
wl
->
tx_blocks_freed
[
i
];
freed_blocks
+=
ac_freed_blocks
;
wl
->
tx_allocated_blocks
[
i
]
-=
ac_freed_blocks
;
/* prevent wrap-around in freed-packets counter */
wl
->
tx_allocated_pkts
[
i
]
-=
(
status
->
tx_released_pkts
[
i
]
-
wl
->
tx_pkts_freed
[
i
])
&
0xff
;
wl
->
tx_blocks_freed
[
i
]
=
le32_to_cpu
(
status
->
tx_released_blks
[
i
]);
wl
->
tx_pkts_freed
[
i
]
=
status
->
tx_released_pkts
[
i
];
}
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
/* Update num of allocated TX blocks per link and ps status */
wl1271_irq_update_links_status
(
wl
,
&
full_status
->
ap
);
wl
->
tx_blocks_available
+=
freed_blocks
;
}
else
{
int
avail
=
full_status
->
sta
.
tx_total
-
wl1271_tx_allocated_blocks
(
wl
);
/* prevent wrap-around in total blocks counter */
if
(
likely
(
wl
->
tx_blocks_freed
<=
le32_to_cpu
(
status
->
total_released_blks
)))
freed_blocks
=
le32_to_cpu
(
status
->
total_released_blks
)
-
wl
->
tx_blocks_freed
;
else
freed_blocks
=
0x100000000LL
-
wl
->
tx_blocks_freed
+
le32_to_cpu
(
status
->
total_released_blks
);
/*
* The FW might change the total number of TX memblocks before
* we get a notification about blocks being released. Thus, the
* available blocks calculation might yield a temporary result
* which is lower than the actual available blocks. Keeping in
* mind that only blocks that were allocated can be moved from
* TX to RX, tx_blocks_available should never decrease here.
*/
wl
->
tx_blocks_available
=
max
((
int
)
wl
->
tx_blocks_available
,
avail
);
}
wl
->
tx_blocks_freed
=
le32_to_cpu
(
status
->
total_released_blks
);
wl
->
tx_allocated_blocks
-=
freed_blocks
;
avail
=
le32_to_cpu
(
status
->
tx_total
)
-
wl
->
tx_allocated_blocks
;
/*
* The FW might change the total number of TX memblocks before
* we get a notification about blocks being released. Thus, the
* available blocks calculation might yield a temporary result
* which is lower than the actual available blocks. Keeping in
* mind that only blocks that were allocated can be moved from
* TX to RX, tx_blocks_available should never decrease here.
*/
wl
->
tx_blocks_available
=
max
((
int
)
wl
->
tx_blocks_available
,
avail
);
/* if more blocks are available now, tx work can be scheduled */
if
(
wl
->
tx_blocks_available
>
old_tx_blk_count
)
clear_bit
(
WL1271_FLAG_FW_TX_BUSY
,
&
wl
->
flags
);
/* for AP update num of allocated TX blocks per link and ps status */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl12xx_irq_update_links_status
(
wl
,
status
);
/* update the host-chipset time offset */
getnstimeofday
(
&
ts
);
wl
->
time_offset
=
(
timespec_to_ns
(
&
ts
)
>>
10
)
-
...
...
@@ -967,8 +955,8 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
clear_bit
(
WL1271_FLAG_IRQ_RUNNING
,
&
wl
->
flags
);
smp_mb__after_clear_bit
();
wl12
71
_fw_status
(
wl
,
wl
->
fw_status
);
intr
=
le32_to_cpu
(
wl
->
fw_status
->
common
.
intr
);
wl12
xx
_fw_status
(
wl
,
wl
->
fw_status
);
intr
=
le32_to_cpu
(
wl
->
fw_status
->
intr
);
intr
&=
WL1271_INTR_MASK
;
if
(
!
intr
)
{
done
=
true
;
...
...
@@ -987,7 +975,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
if
(
likely
(
intr
&
WL1271_ACX_INTR_DATA
))
{
wl1271_debug
(
DEBUG_IRQ
,
"WL1271_ACX_INTR_DATA"
);
wl12
71_rx
(
wl
,
&
wl
->
fw_status
->
common
);
wl12
xx_rx
(
wl
,
wl
->
fw_status
);
/* Check if any tx blocks were freed */
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
...
...
@@ -1004,7 +992,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
}
/* check for tx results */
if
(
wl
->
fw_status
->
common
.
tx_results_counter
!=
if
(
wl
->
fw_status
->
tx_results_counter
!=
(
wl
->
tx_results_count
&
0xff
))
wl1271_tx_complete
(
wl
);
...
...
@@ -1056,25 +1044,10 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
const
char
*
fw_name
;
int
ret
;
switch
(
wl
->
bss_type
)
{
case
BSS_TYPE_AP_BSS
:
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fw_name
=
WL128X_AP_FW_NAME
;
else
fw_name
=
WL127X_AP_FW_NAME
;
break
;
case
BSS_TYPE_IBSS
:
case
BSS_TYPE_STA_BSS
:
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fw_name
=
WL128X_FW_NAME
;
else
fw_name
=
WL1271_FW_NAME
;
break
;
default:
wl1271_error
(
"no compatible firmware for bss_type %d"
,
wl
->
bss_type
);
return
-
EINVAL
;
}
if
(
wl
->
chip
.
id
==
CHIP_ID_1283_PG20
)
fw_name
=
WL128X_FW_NAME
;
else
fw_name
=
WL127X_FW_NAME
;
wl1271_debug
(
DEBUG_BOOT
,
"booting firmware %s"
,
fw_name
);
...
...
@@ -1103,7 +1076,6 @@ static int wl1271_fetch_firmware(struct wl1271 *wl)
}
memcpy
(
wl
->
fw
,
fw
->
data
,
wl
->
fw_len
);
wl
->
fw_bss_type
=
wl
->
bss_type
;
ret
=
0
;
out:
...
...
@@ -1194,8 +1166,8 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
wl12xx_cmd_stop_fwlog
(
wl
);
/* Read the first memory block address */
wl12
71
_fw_status
(
wl
,
wl
->
fw_status
);
first_addr
=
__le32_to_cpu
(
wl
->
fw_status
->
sta
.
log_start_addr
);
wl12
xx
_fw_status
(
wl
,
wl
->
fw_status
);
first_addr
=
le32_to_cpu
(
wl
->
fw_status
->
log_start_addr
);
if
(
!
first_addr
)
goto
out
;
...
...
@@ -1211,7 +1183,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
* of each memory block hold the hardware address of the next
* one. The last memory block points to the first one.
*/
addr
=
__
le32_to_cpup
((
__le32
*
)
block
);
addr
=
le32_to_cpup
((
__le32
*
)
block
);
if
(
!
wl12xx_copy_fwlog
(
wl
,
block
+
sizeof
(
addr
),
WL12XX_HW_BLOCK_SIZE
-
sizeof
(
addr
)))
break
;
...
...
@@ -1374,8 +1346,7 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
goto
out
;
}
/* Make sure the firmware type matches the BSS type */
if
(
wl
->
fw
==
NULL
||
wl
->
fw_bss_type
!=
wl
->
bss_type
)
{
if
(
wl
->
fw
==
NULL
)
{
ret
=
wl1271_fetch_firmware
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -1395,6 +1366,7 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
int
wl1271_plt_start
(
struct
wl1271
*
wl
)
{
int
retries
=
WL1271_BOOT_RETRIES
;
struct
wiphy
*
wiphy
=
wl
->
hw
->
wiphy
;
int
ret
;
mutex_lock
(
&
wl
->
mutex
);
...
...
@@ -1428,6 +1400,11 @@ int wl1271_plt_start(struct wl1271 *wl)
wl1271_notice
(
"firmware booted in PLT mode (%s)"
,
wl
->
chip
.
fw_ver_str
);
/* update hw/fw version info in wiphy struct */
wiphy
->
hw_version
=
wl
->
chip
.
id
;
strncpy
(
wiphy
->
fw_version
,
wl
->
chip
.
fw_ver_str
,
sizeof
(
wiphy
->
fw_version
));
goto
out
;
irq_disable:
...
...
@@ -1504,10 +1481,25 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
q
=
wl1271_tx_get_queue
(
mapping
);
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
hlid
=
wl12
71_tx_get_hlid
(
skb
);
hlid
=
wl12
xx_tx_get_hlid_ap
(
wl
,
skb
);
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
/* queue the packet */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
if
(
!
wl1271_is_active_sta
(
wl
,
hlid
))
{
wl1271_debug
(
DEBUG_TX
,
"DROP skb hlid %d q %d"
,
hlid
,
q
);
dev_kfree_skb
(
skb
);
goto
out
;
}
wl1271_debug
(
DEBUG_TX
,
"queue skb hlid %d q %d"
,
hlid
,
q
);
skb_queue_tail
(
&
wl
->
links
[
hlid
].
tx_queue
[
q
],
skb
);
}
else
{
skb_queue_tail
(
&
wl
->
tx_queue
[
q
],
skb
);
}
wl
->
tx_queue_count
[
q
]
++
;
/*
...
...
@@ -1520,14 +1512,6 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
set_bit
(
q
,
&
wl
->
stopped_queues_map
);
}
/* queue the packet */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
wl1271_debug
(
DEBUG_TX
,
"queue skb hlid %d q %d"
,
hlid
,
q
);
skb_queue_tail
(
&
wl
->
links
[
hlid
].
tx_queue
[
q
],
skb
);
}
else
{
skb_queue_tail
(
&
wl
->
tx_queue
[
q
],
skb
);
}
/*
* The chip specific setup must run before the first TX packet -
* before that, the tx_work will not be initialized!
...
...
@@ -1537,6 +1521,7 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
!
test_bit
(
WL1271_FLAG_TX_PENDING
,
&
wl
->
flags
))
ieee80211_queue_work
(
wl
->
hw
,
&
wl
->
tx_work
);
out:
spin_unlock_irqrestore
(
&
wl
->
wl_lock
,
flags
);
}
...
...
@@ -1673,7 +1658,7 @@ static int wl1271_configure_suspend_ap(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_unlock
;
ret
=
wl1271_acx_
set_ap_beacon_filter
(
wl
,
true
);
ret
=
wl1271_acx_
beacon_filter_opt
(
wl
,
true
);
wl1271_ps_elp_sleep
(
wl
);
out_unlock:
...
...
@@ -1711,7 +1696,7 @@ static void wl1271_configure_resume(struct wl1271 *wl)
wl1271_ps_set_mode
(
wl
,
STATION_ACTIVE_MODE
,
wl
->
basic_rate
,
true
);
}
else
if
(
is_ap
)
{
wl1271_acx_
set_ap_beacon_filter
(
wl
,
false
);
wl1271_acx_
beacon_filter_opt
(
wl
,
false
);
}
wl1271_ps_elp_sleep
(
wl
);
...
...
@@ -1803,9 +1788,6 @@ static int wl1271_op_start(struct ieee80211_hw *hw)
*
* The MAC address is first known when the corresponding interface
* is added. That is where we will initialize the hardware.
*
* In addition, we currently have different firmwares for AP and managed
* operation. We will know which to boot according to interface type.
*/
return
0
;
...
...
@@ -1816,6 +1798,24 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 stop"
);
}
static
u8
wl12xx_get_role_type
(
struct
wl1271
*
wl
)
{
switch
(
wl
->
bss_type
)
{
case
BSS_TYPE_AP_BSS
:
return
WL1271_ROLE_AP
;
case
BSS_TYPE_STA_BSS
:
return
WL1271_ROLE_STA
;
case
BSS_TYPE_IBSS
:
return
WL1271_ROLE_IBSS
;
default:
wl1271_error
(
"invalid bss_type: %d"
,
wl
->
bss_type
);
}
return
WL12XX_INVALID_ROLE_TYPE
;
}
static
int
wl1271_op_add_interface
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
...
...
@@ -1823,6 +1823,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
struct
wiphy
*
wiphy
=
hw
->
wiphy
;
int
retries
=
WL1271_BOOT_RETRIES
;
int
ret
=
0
;
u8
role_type
;
bool
booted
=
false
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 add interface type %d mac %pM"
,
...
...
@@ -1863,6 +1864,11 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
goto
out
;
}
role_type
=
wl12xx_get_role_type
(
wl
);
if
(
role_type
==
WL12XX_INVALID_ROLE_TYPE
)
{
ret
=
-
EINVAL
;
goto
out
;
}
memcpy
(
wl
->
mac_addr
,
vif
->
addr
,
ETH_ALEN
);
if
(
wl
->
state
!=
WL1271_STATE_OFF
)
{
...
...
@@ -1882,6 +1888,25 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
power_off
;
if
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
||
wl
->
bss_type
==
BSS_TYPE_IBSS
)
{
/*
* The device role is a special role used for
* rx and tx frames prior to association (as
* the STA role can get packets only from
* its associated bssid)
*/
ret
=
wl12xx_cmd_role_enable
(
wl
,
WL1271_ROLE_DEVICE
,
&
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
irq_disable
;
}
ret
=
wl12xx_cmd_role_enable
(
wl
,
role_type
,
&
wl
->
role_id
);
if
(
ret
<
0
)
goto
irq_disable
;
ret
=
wl1271_hw_init
(
wl
);
if
(
ret
<
0
)
goto
irq_disable
;
...
...
@@ -1946,7 +1971,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
)
{
int
i
;
int
ret
,
i
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 remove interface"
);
...
...
@@ -1971,6 +1996,31 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
ieee80211_scan_completed
(
wl
->
hw
,
true
);
}
if
(
!
test_bit
(
WL1271_FLAG_RECOVERY_IN_PROGRESS
,
&
wl
->
flags
))
{
/* disable active roles */
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
deinit
;
if
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
)
{
ret
=
wl12xx_cmd_role_disable
(
wl
,
&
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
deinit
;
}
ret
=
wl12xx_cmd_role_disable
(
wl
,
&
wl
->
role_id
);
if
(
ret
<
0
)
goto
deinit
;
wl1271_ps_elp_sleep
(
wl
);
}
deinit:
/* clear all hlids (except system_hlid) */
wl
->
sta_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
dev_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_bcast_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_global_hlid
=
WL12XX_INVALID_LINK_ID
;
/*
* this must be before the cancel_work calls below, so that the work
* functions don't perform further work.
...
...
@@ -2007,18 +2057,26 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
wl
->
psm_entry_retry
=
0
;
wl
->
power_level
=
WL1271_DEFAULT_POWER_LEVEL
;
wl
->
tx_blocks_available
=
0
;
wl
->
tx_allocated_blocks
=
0
;
wl
->
tx_results_count
=
0
;
wl
->
tx_packets_count
=
0
;
wl
->
time_offset
=
0
;
wl
->
session_counter
=
0
;
wl
->
rate_set
=
CONF_TX_RATE_MASK_BASIC
;
wl
->
vif
=
NULL
;
wl
->
filters
=
0
;
wl1271_free_ap_keys
(
wl
);
memset
(
wl
->
ap_hlid_map
,
0
,
sizeof
(
wl
->
ap_hlid_map
));
wl
->
ap_fw_ps_map
=
0
;
wl
->
ap_ps_map
=
0
;
wl
->
sched_scanning
=
false
;
wl
->
role_id
=
WL12XX_INVALID_ROLE_ID
;
wl
->
dev_role_id
=
WL12XX_INVALID_ROLE_ID
;
memset
(
wl
->
roles_map
,
0
,
sizeof
(
wl
->
roles_map
));
memset
(
wl
->
links_map
,
0
,
sizeof
(
wl
->
links_map
));
memset
(
wl
->
roc_map
,
0
,
sizeof
(
wl
->
roc_map
));
/* The system link is always allocated */
__set_bit
(
WL12XX_SYSTEM_HLID
,
wl
->
links_map
);
/*
* this is performed after the cancel_work calls and the associated
...
...
@@ -2027,9 +2085,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
*/
wl
->
flags
=
0
;
wl
->
tx_blocks_freed
=
0
;
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
wl
->
tx_
block
s_freed
[
i
]
=
0
;
wl
->
tx_allocated_
block
s
[
i
]
=
0
;
wl
->
tx_
pkt
s_freed
[
i
]
=
0
;
wl
->
tx_allocated_
pkt
s
[
i
]
=
0
;
}
wl1271_debugfs_reset
(
wl
);
...
...
@@ -2061,64 +2121,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
cancel_work_sync
(
&
wl
->
recovery_work
);
}
void
wl1271_configure_filters
(
struct
wl1271
*
wl
,
unsigned
int
filters
)
{
wl1271_set_default_filters
(
wl
);
/* combine requested filters with current filter config */
filters
=
wl
->
filters
|
filters
;
wl1271_debug
(
DEBUG_FILTERS
,
"RX filters set: "
);
if
(
filters
&
FIF_PROMISC_IN_BSS
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_PROMISC_IN_BSS"
);
wl
->
rx_config
&=
~
CFG_UNI_FILTER_EN
;
wl
->
rx_config
|=
CFG_BSSID_FILTER_EN
;
}
if
(
filters
&
FIF_BCN_PRBRESP_PROMISC
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_BCN_PRBRESP_PROMISC"
);
wl
->
rx_config
&=
~
CFG_BSSID_FILTER_EN
;
wl
->
rx_config
&=
~
CFG_SSID_FILTER_EN
;
}
if
(
filters
&
FIF_OTHER_BSS
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_OTHER_BSS"
);
wl
->
rx_config
&=
~
CFG_BSSID_FILTER_EN
;
}
if
(
filters
&
FIF_CONTROL
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_CONTROL"
);
wl
->
rx_filter
|=
CFG_RX_CTL_EN
;
}
if
(
filters
&
FIF_FCSFAIL
)
{
wl1271_debug
(
DEBUG_FILTERS
,
" - FIF_FCSFAIL"
);
wl
->
rx_filter
|=
CFG_RX_FCS_ERROR
;
}
}
static
int
wl1271_dummy_join
(
struct
wl1271
*
wl
)
{
int
ret
=
0
;
/* we need to use a dummy BSSID for now */
static
const
u8
dummy_bssid
[
ETH_ALEN
]
=
{
0x0b
,
0xad
,
0xde
,
0xad
,
0xbe
,
0xef
};
memcpy
(
wl
->
bssid
,
dummy_bssid
,
ETH_ALEN
);
/* pass through frames from all BSS */
wl1271_configure_filters
(
wl
,
FIF_OTHER_BSS
);
ret
=
wl1271_cmd_join
(
wl
,
wl
->
set_bss_type
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
);
out:
return
ret
;
}
static
int
wl1271_join
(
struct
wl1271
*
wl
,
bool
set_assoc
)
{
int
ret
;
bool
is_ibss
=
(
wl
->
bss_type
==
BSS_TYPE_IBSS
);
/*
* One of the side effects of the JOIN command is that is clears
...
...
@@ -2135,12 +2141,13 @@ static int wl1271_join(struct wl1271 *wl, bool set_assoc)
if
(
set_assoc
)
set_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
ret
=
wl1271_cmd_join
(
wl
,
wl
->
set_bss_type
);
if
(
is_ibss
)
ret
=
wl12xx_cmd_role_start_ibss
(
wl
);
else
ret
=
wl12xx_cmd_role_start_sta
(
wl
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
);
if
(
!
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
goto
out
;
...
...
@@ -2176,20 +2183,16 @@ static int wl1271_unjoin(struct wl1271 *wl)
int
ret
;
/* to stop listening to a channel, we disconnect */
ret
=
wl12
71_cmd_disconnect
(
wl
);
ret
=
wl12
xx_cmd_role_stop_sta
(
wl
);
if
(
ret
<
0
)
goto
out
;
clear_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
);
memset
(
wl
->
bssid
,
0
,
ETH_ALEN
);
/* reset TX security counters on a clean disconnect */
wl
->
tx_security_last_seq_lsb
=
0
;
wl
->
tx_security_seq
=
0
;
/* stop filtering packets based on bssid */
wl1271_configure_filters
(
wl
,
FIF_OTHER_BSS
);
out:
return
ret
;
}
...
...
@@ -2202,13 +2205,29 @@ static void wl1271_set_band_rate(struct wl1271 *wl)
wl
->
basic_rate_set
=
wl
->
conf
.
tx
.
basic_rate_5
;
}
static
bool
wl12xx_is_roc
(
struct
wl1271
*
wl
)
{
u8
role_id
;
role_id
=
find_first_bit
(
wl
->
roc_map
,
WL12XX_MAX_ROLES
);
if
(
role_id
>=
WL12XX_MAX_ROLES
)
return
false
;
return
true
;
}
static
int
wl1271_sta_handle_idle
(
struct
wl1271
*
wl
,
bool
idle
)
{
int
ret
;
if
(
idle
)
{
if
(
test_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
))
{
ret
=
wl1271_unjoin
(
wl
);
/* no need to croc if we weren't busy (e.g. during boot) */
if
(
wl12xx_is_roc
(
wl
))
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_cmd_role_stop_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
...
...
@@ -2223,18 +2242,17 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
goto
out
;
set_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
);
}
else
{
/* increment the session counter */
wl
->
session_counter
++
;
if
(
wl
->
session_counter
>=
SESSION_COUNTER_MAX
)
wl
->
session_counter
=
0
;
/* The current firmware only supports sched_scan in idle */
if
(
wl
->
sched_scanning
)
{
wl1271_scan_sched_scan_stop
(
wl
);
ieee80211_sched_scan_stopped
(
wl
->
hw
);
}
ret
=
wl1271_dummy_join
(
wl
);
ret
=
wl12xx_cmd_role_start_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
clear_bit
(
WL1271_FLAG_IDLE
,
&
wl
->
flags
);
...
...
@@ -2314,11 +2332,34 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
wl1271_warning
(
"rate policy for channel "
"failed %d"
,
ret
);
if
(
test_bit
(
WL1271_FLAG_JOINED
,
&
wl
->
flags
))
{
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
{
if
(
wl12xx_is_roc
(
wl
))
{
/* roaming */
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out_sleep
;
}
ret
=
wl1271_join
(
wl
,
false
);
if
(
ret
<
0
)
wl1271_warning
(
"cmd join on channel "
"failed %d"
,
ret
);
}
else
{
/*
* change the ROC channel. do it only if we are
* not idle. otherwise, CROC will be called
* anyway.
*/
if
(
wl12xx_is_roc
(
wl
)
&&
!
(
conf
->
flags
&
IEEE80211_CONF_IDLE
))
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out_sleep
;
ret
=
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
wl1271_warning
(
"roc failed %d"
,
ret
);
}
}
}
}
...
...
@@ -2458,18 +2499,11 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
goto
out_sleep
;
}
/* determine, whether supported filter values have changed */
if
(
changed
==
0
)
goto
out_sleep
;
/* configure filters */
wl
->
filters
=
*
total
;
wl1271_configure_filters
(
wl
,
0
);
/* apply configured filters */
ret
=
wl1271_acx_rx_config
(
wl
,
wl
->
rx_config
,
wl
->
rx_filter
);
if
(
ret
<
0
)
goto
out_sleep
;
/*
* the fw doesn't provide an api to configure the filters. instead,
* the filters configuration is based on the active roles / ROC
* state.
*/
out_sleep:
wl1271_ps_elp_sleep
(
wl
);
...
...
@@ -2541,14 +2575,19 @@ static int wl1271_ap_init_hwenc(struct wl1271 *wl)
bool
wep_key_added
=
false
;
for
(
i
=
0
;
i
<
MAX_NUM_KEYS
;
i
++
)
{
u8
hlid
;
if
(
wl
->
recorded_ap_keys
[
i
]
==
NULL
)
break
;
key
=
wl
->
recorded_ap_keys
[
i
];
hlid
=
key
->
hlid
;
if
(
hlid
==
WL12XX_INVALID_LINK_ID
)
hlid
=
wl
->
ap_bcast_hlid
;
ret
=
wl1271_cmd_set_ap_key
(
wl
,
KEY_ADD_OR_REPLACE
,
key
->
id
,
key
->
key_type
,
key
->
key_size
,
key
->
key
,
key
->
hlid
,
key
->
tx_seq_32
,
hlid
,
key
->
tx_seq_32
,
key
->
tx_seq_16
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -2558,7 +2597,8 @@ static int wl1271_ap_init_hwenc(struct wl1271 *wl)
}
if
(
wep_key_added
)
{
ret
=
wl1271_cmd_set_ap_default_wep_key
(
wl
,
wl
->
default_key
);
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
wl
->
default_key
,
wl
->
ap_bcast_hlid
);
if
(
ret
<
0
)
goto
out
;
}
...
...
@@ -2583,7 +2623,7 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
wl_sta
=
(
struct
wl1271_station
*
)
sta
->
drv_priv
;
hlid
=
wl_sta
->
hlid
;
}
else
{
hlid
=
WL1271_AP_BROADCAST_HLID
;
hlid
=
wl
->
ap_bcast_hlid
;
}
if
(
!
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
{
...
...
@@ -2627,6 +2667,11 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
if
(
action
==
KEY_REMOVE
&&
!
is_broadcast_ether_addr
(
addr
))
return
0
;
/* don't remove key if hlid was already deleted */
if
(
action
==
KEY_REMOVE
&&
wl
->
sta_hlid
==
WL12XX_INVALID_LINK_ID
)
return
0
;
ret
=
wl1271_cmd_set_sta_key
(
wl
,
action
,
id
,
key_type
,
key_size
,
key
,
addr
,
tx_seq_32
,
...
...
@@ -2636,8 +2681,9 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
/* the default WEP key needs to be configured at least once */
if
(
key_type
==
KEY_WEP
)
{
ret
=
wl1271_cmd_set_sta_default_wep_key
(
wl
,
wl
->
default_key
);
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
wl
->
default_key
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
return
ret
;
}
...
...
@@ -2779,10 +2825,20 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_scan
(
hw
->
priv
,
ssid
,
len
,
req
);
/* cancel ROC before scanning */
if
(
wl12xx_is_roc
(
wl
))
{
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
{
/* don't allow scanning right now */
ret
=
-
EBUSY
;
goto
out_sleep
;
}
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
wl12xx_cmd_role_stop_dev
(
wl
);
}
ret
=
wl1271_scan
(
hw
->
priv
,
ssid
,
len
,
req
);
out_sleep:
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
...
...
@@ -3094,20 +3150,20 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
if
((
changed
&
BSS_CHANGED_BEACON_ENABLED
))
{
if
(
bss_conf
->
enable_beacon
)
{
if
(
!
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
{
ret
=
wl12
71_cmd_start_bss
(
wl
);
ret
=
wl12
xx_cmd_role_start_ap
(
wl
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
);
wl1271_debug
(
DEBUG_AP
,
"started AP"
);
ret
=
wl1271_ap_init_hwenc
(
wl
);
if
(
ret
<
0
)
goto
out
;
set_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
);
wl1271_debug
(
DEBUG_AP
,
"started AP"
);
}
}
else
{
if
(
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
{
ret
=
wl12
71_cmd_stop_bss
(
wl
);
ret
=
wl12
xx_cmd_role_stop_ap
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -3120,6 +3176,18 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
ret
=
wl1271_bss_erp_info_changed
(
wl
,
bss_conf
,
changed
);
if
(
ret
<
0
)
goto
out
;
/* Handle HT information change */
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_information
(
wl
,
bss_conf
->
ht_operation_mode
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht information failed %d"
,
ret
);
goto
out
;
}
}
out:
return
;
}
...
...
@@ -3132,6 +3200,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
{
bool
do_join
=
false
,
set_assoc
=
false
;
bool
is_ibss
=
(
wl
->
bss_type
==
BSS_TYPE_IBSS
);
bool
ibss_joined
=
false
;
u32
sta_rate_set
=
0
;
int
ret
;
struct
ieee80211_sta
*
sta
;
...
...
@@ -3145,14 +3214,28 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
goto
out
;
}
if
((
changed
&
BSS_CHANGED_BEACON_INT
)
&&
is_ibss
)
if
(
changed
&
BSS_CHANGED_IBSS
)
{
if
(
bss_conf
->
ibss_joined
)
{
set_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
);
ibss_joined
=
true
;
}
else
{
if
(
test_and_clear_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
))
{
wl1271_unjoin
(
wl
);
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
}
}
}
if
((
changed
&
BSS_CHANGED_BEACON_INT
)
&&
ibss_joined
)
do_join
=
true
;
/* Need to update the SSID (for filtering etc) */
if
((
changed
&
BSS_CHANGED_BEACON
)
&&
i
s_ibss
)
if
((
changed
&
BSS_CHANGED_BEACON
)
&&
i
bss_joined
)
do_join
=
true
;
if
((
changed
&
BSS_CHANGED_BEACON_ENABLED
)
&&
i
s_ibss
)
{
if
((
changed
&
BSS_CHANGED_BEACON_ENABLED
)
&&
i
bss_joined
)
{
wl1271_debug
(
DEBUG_ADHOC
,
"ad-hoc beaconing: %s"
,
bss_conf
->
enable_beacon
?
"enabled"
:
"disabled"
);
...
...
@@ -3192,17 +3275,17 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
if
(
ret
<
0
)
goto
out
;
/* filter out all packets not from this BSSID */
wl1271_configure_filters
(
wl
,
0
);
/* Need to update the BSSID (for filtering etc) */
do_join
=
true
;
}
}
rcu_read_lock
();
sta
=
ieee80211_find_sta
(
vif
,
bss_conf
->
bssid
);
if
(
sta
)
{
if
(
changed
&
(
BSS_CHANGED_ASSOC
|
BSS_CHANGED_HT
))
{
rcu_read_lock
();
sta
=
ieee80211_find_sta
(
vif
,
bss_conf
->
bssid
);
if
(
!
sta
)
goto
sta_not_found
;
/* save the supp_rates of the ap */
sta_rate_set
=
sta
->
supp_rates
[
wl
->
hw
->
conf
.
channel
->
band
];
if
(
sta
->
ht_cap
.
ht_supported
)
...
...
@@ -3210,38 +3293,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
(
sta
->
ht_cap
.
mcs
.
rx_mask
[
0
]
<<
HW_HT_RATES_OFFSET
);
sta_ht_cap
=
sta
->
ht_cap
;
sta_exists
=
true
;
}
rcu_read_unlock
();
if
(
sta_exists
)
{
/* handle new association with HT and HT information change */
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
true
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap true failed %d"
,
ret
);
goto
out
;
}
ret
=
wl1271_acx_set_ht_information
(
wl
,
bss_conf
->
ht_operation_mode
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht information failed %d"
,
ret
);
goto
out
;
}
}
/* handle new association without HT and disassociation */
else
if
(
changed
&
BSS_CHANGED_ASSOC
)
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
false
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap false failed %d"
,
ret
);
goto
out
;
}
}
sta_not_found:
rcu_read_unlock
();
}
if
((
changed
&
BSS_CHANGED_ASSOC
))
{
...
...
@@ -3309,7 +3363,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
bool
was_assoc
=
!!
test_and_clear_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
);
clear_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
);
bool
was_ifup
=
!!
test_and_clear_bit
(
WL1271_FLAG_STA_STATE_SENT
,
&
wl
->
flags
);
wl
->
aid
=
0
;
/* free probe-request template */
...
...
@@ -3336,8 +3392,32 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
/* restore the bssid filter and go to dummy bssid */
if
(
was_assoc
)
{
u32
conf_flags
=
wl
->
hw
->
conf
.
flags
;
/*
* we might have to disable roc, if there was
* no IF_OPER_UP notification.
*/
if
(
!
was_ifup
)
{
ret
=
wl12xx_croc
(
wl
,
wl
->
role_id
);
if
(
ret
<
0
)
goto
out
;
}
/*
* (we also need to disable roc in case of
* roaming on the same channel. until we will
* have a better flow...)
*/
if
(
test_bit
(
wl
->
dev_role_id
,
wl
->
roc_map
))
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
}
wl1271_unjoin
(
wl
);
wl1271_dummy_join
(
wl
);
if
(
!
(
conf_flags
&
IEEE80211_CONF_IDLE
))
{
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
}
}
}
}
...
...
@@ -3398,7 +3478,68 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
wl1271_warning
(
"cmd join failed %d"
,
ret
);
goto
out
;
}
wl1271_check_operstate
(
wl
,
ieee80211_get_operstate
(
vif
));
/* ROC until connected (after EAPOL exchange) */
if
(
!
is_ibss
)
{
ret
=
wl12xx_roc
(
wl
,
wl
->
role_id
);
if
(
ret
<
0
)
goto
out
;
wl1271_check_operstate
(
wl
,
ieee80211_get_operstate
(
vif
));
}
/*
* stop device role if started (we might already be in
* STA role). TODO: make it better.
*/
if
(
wl
->
dev_role_id
!=
WL12XX_INVALID_ROLE_ID
)
{
ret
=
wl12xx_croc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_cmd_role_stop_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
}
}
/* Handle new association with HT. Do this after join. */
if
(
sta_exists
)
{
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
true
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap true failed %d"
,
ret
);
goto
out
;
}
}
/* handle new association without HT and disassociation */
else
if
(
changed
&
BSS_CHANGED_ASSOC
)
{
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta_ht_cap
,
false
,
wl
->
sta_hlid
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht cap false failed %d"
,
ret
);
goto
out
;
}
}
}
/* Handle HT information change. Done after join. */
if
((
changed
&
BSS_CHANGED_HT
)
&&
(
bss_conf
->
channel_type
!=
NL80211_CHAN_NO_HT
))
{
ret
=
wl1271_acx_set_ht_information
(
wl
,
bss_conf
->
ht_operation_mode
);
if
(
ret
<
0
)
{
wl1271_warning
(
"Set ht information failed %d"
,
ret
);
goto
out
;
}
}
out:
...
...
@@ -3568,7 +3709,7 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
}
wl_sta
=
(
struct
wl1271_station
*
)
sta
->
drv_priv
;
__
set_bit
(
id
,
wl
->
ap_hlid_map
);
set_bit
(
id
,
wl
->
ap_hlid_map
);
wl_sta
->
hlid
=
WL1271_AP_STA_HLID_START
+
id
;
*
hlid
=
wl_sta
->
hlid
;
memcpy
(
wl
->
links
[
wl_sta
->
hlid
].
addr
,
sta
->
addr
,
ETH_ALEN
);
...
...
@@ -3582,19 +3723,14 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
if
(
WARN_ON
(
!
test_bit
(
id
,
wl
->
ap_hlid_map
)))
return
;
__
clear_bit
(
id
,
wl
->
ap_hlid_map
);
clear_bit
(
id
,
wl
->
ap_hlid_map
);
memset
(
wl
->
links
[
hlid
].
addr
,
0
,
ETH_ALEN
);
wl
->
links
[
hlid
].
ba_bitmap
=
0
;
wl1271_tx_reset_link_queues
(
wl
,
hlid
);
__clear_bit
(
hlid
,
&
wl
->
ap_ps_map
);
__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
)
...
...
@@ -3621,7 +3757,15 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
out_free_sta
;
ret
=
wl1271_cmd_add_sta
(
wl
,
sta
,
hlid
);
ret
=
wl12xx_cmd_add_peer
(
wl
,
sta
,
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
ret
=
wl12xx_cmd_set_peer_state
(
wl
,
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
ret
=
wl1271_acx_set_ht_capabilities
(
wl
,
&
sta
->
ht_cap
,
true
,
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
...
...
@@ -3664,7 +3808,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
if
(
ret
<
0
)
goto
out
;
ret
=
wl12
71_cmd_remove_sta
(
wl
,
wl_sta
->
hlid
);
ret
=
wl12
xx_cmd_remove_peer
(
wl
,
wl_sta
->
hlid
);
if
(
ret
<
0
)
goto
out_sleep
;
...
...
@@ -3686,6 +3830,14 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
{
struct
wl1271
*
wl
=
hw
->
priv
;
int
ret
;
u8
hlid
,
*
ba_bitmap
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 ampdu action %d tid %d"
,
action
,
tid
);
/* sanity check - the fields in FW are only 8bits wide */
if
(
WARN_ON
(
tid
>
0xFF
))
return
-
ENOTSUPP
;
mutex_lock
(
&
wl
->
mutex
);
...
...
@@ -3694,6 +3846,20 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
goto
out
;
}
if
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
)
{
hlid
=
wl
->
sta_hlid
;
ba_bitmap
=
&
wl
->
ba_rx_bitmap
;
}
else
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
struct
wl1271_station
*
wl_sta
;
wl_sta
=
(
struct
wl1271_station
*
)
sta
->
drv_priv
;
hlid
=
wl_sta
->
hlid
;
ba_bitmap
=
&
wl
->
links
[
hlid
].
ba_bitmap
;
}
else
{
ret
=
-
EINVAL
;
goto
out
;
}
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
...
...
@@ -3703,20 +3869,46 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
switch
(
action
)
{
case
IEEE80211_AMPDU_RX_START
:
if
((
wl
->
ba_support
)
&&
(
wl
->
ba_allowed
))
{
ret
=
wl1271_acx_set_ba_receiver_session
(
wl
,
tid
,
*
ssn
,
true
);
if
(
!
ret
)
wl
->
ba_rx_bitmap
|=
BIT
(
tid
);
}
else
{
if
(
!
wl
->
ba_support
||
!
wl
->
ba_allowed
)
{
ret
=
-
ENOTSUPP
;
break
;
}
if
(
wl
->
ba_rx_session_count
>=
RX_BA_MAX_SESSIONS
)
{
ret
=
-
EBUSY
;
wl1271_error
(
"exceeded max RX BA sessions"
);
break
;
}
if
(
*
ba_bitmap
&
BIT
(
tid
))
{
ret
=
-
EINVAL
;
wl1271_error
(
"cannot enable RX BA session on active "
"tid: %d"
,
tid
);
break
;
}
ret
=
wl12xx_acx_set_ba_receiver_session
(
wl
,
tid
,
*
ssn
,
true
,
hlid
);
if
(
!
ret
)
{
*
ba_bitmap
|=
BIT
(
tid
);
wl
->
ba_rx_session_count
++
;
}
break
;
case
IEEE80211_AMPDU_RX_STOP
:
ret
=
wl1271_acx_set_ba_receiver_session
(
wl
,
tid
,
0
,
false
);
if
(
!
ret
)
wl
->
ba_rx_bitmap
&=
~
BIT
(
tid
);
if
(
!
(
*
ba_bitmap
&
BIT
(
tid
)))
{
ret
=
-
EINVAL
;
wl1271_error
(
"no active RX BA session on tid: %d"
,
tid
);
break
;
}
ret
=
wl12xx_acx_set_ba_receiver_session
(
wl
,
tid
,
0
,
false
,
hlid
);
if
(
!
ret
)
{
*
ba_bitmap
&=
~
BIT
(
tid
);
wl
->
ba_rx_session_count
--
;
}
break
;
/*
...
...
@@ -4126,7 +4318,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
return
len
;
}
static
DEVICE_ATTR
(
hw_pg_ver
,
S_IRUGO
|
S_IWUSR
,
static
DEVICE_ATTR
(
hw_pg_ver
,
S_IRUGO
,
wl1271_sysfs_show_hw_pg_ver
,
NULL
);
static
ssize_t
wl1271_sysfs_read_fwlog
(
struct
file
*
filp
,
struct
kobject
*
kobj
,
...
...
@@ -4288,7 +4480,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
* should be the maximum length possible for a template, without
* the IEEE80211 header of the template
*/
wl
->
hw
->
wiphy
->
max_scan_ie_len
=
WL1271_CMD_TEMPL_
MAX
_SIZE
-
wl
->
hw
->
wiphy
->
max_scan_ie_len
=
WL1271_CMD_TEMPL_
DFLT
_SIZE
-
sizeof
(
struct
ieee80211_header
);
/* make sure all our channels fit in the scanned_ch bitmask */
...
...
@@ -4387,8 +4579,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
beacon_int
=
WL1271_DEFAULT_BEACON_INT
;
wl
->
default_key
=
0
;
wl
->
rx_counter
=
0
;
wl
->
rx_config
=
WL1271_DEFAULT_STA_RX_CONFIG
;
wl
->
rx_filter
=
WL1271_DEFAULT_STA_RX_FILTER
;
wl
->
psm_entry_retry
=
0
;
wl
->
power_level
=
WL1271_DEFAULT_POWER_LEVEL
;
wl
->
basic_rate_set
=
CONF_TX_RATE_MASK_BASIC
;
...
...
@@ -4401,7 +4591,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
hw_pg_ver
=
-
1
;
wl
->
bss_type
=
MAX_BSS_TYPE
;
wl
->
set_bss_type
=
MAX_BSS_TYPE
;
wl
->
fw_bss_type
=
MAX_BSS_TYPE
;
wl
->
last_tx_hlid
=
0
;
wl
->
ap_ps_map
=
0
;
wl
->
ap_fw_ps_map
=
0
;
...
...
@@ -4410,12 +4599,22 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
sched_scanning
=
false
;
wl
->
tx_security_seq
=
0
;
wl
->
tx_security_last_seq_lsb
=
0
;
wl
->
role_id
=
WL12XX_INVALID_ROLE_ID
;
wl
->
system_hlid
=
WL12XX_SYSTEM_HLID
;
wl
->
sta_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
dev_role_id
=
WL12XX_INVALID_ROLE_ID
;
wl
->
dev_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
session_counter
=
0
;
wl
->
ap_bcast_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_global_hlid
=
WL12XX_INVALID_LINK_ID
;
setup_timer
(
&
wl
->
rx_streaming_timer
,
wl1271_rx_streaming_timer
,
(
unsigned
long
)
wl
);
wl
->
fwlog_size
=
0
;
init_waitqueue_head
(
&
wl
->
fwlog_waitq
);
/* The system link is always allocated */
__set_bit
(
WL12XX_SYSTEM_HLID
,
wl
->
links_map
);
memset
(
wl
->
tx_frames_map
,
0
,
sizeof
(
wl
->
tx_frames_map
));
for
(
i
=
0
;
i
<
ACX_TX_DESCRIPTORS
;
i
++
)
wl
->
tx_frames
[
i
]
=
NULL
;
...
...
@@ -4522,6 +4721,10 @@ int wl1271_free_hw(struct wl1271 *wl)
mutex_unlock
(
&
wl
->
mutex
);
device_remove_bin_file
(
&
wl
->
plat_dev
->
dev
,
&
fwlog_attr
);
device_remove_file
(
&
wl
->
plat_dev
->
dev
,
&
dev_attr_hw_pg_ver
);
device_remove_file
(
&
wl
->
plat_dev
->
dev
,
&
dev_attr_bt_coex_state
);
platform_device_unregister
(
wl
->
plat_dev
);
free_page
((
unsigned
long
)
wl
->
fwlog
);
dev_kfree_skb
(
wl
->
dummy_packet
);
...
...
drivers/net/wireless/wl12xx/ps.c
浏览文件 @
e0a8c583
...
...
@@ -226,8 +226,8 @@ void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues)
if
(
test_bit
(
hlid
,
&
wl
->
ap_ps_map
))
return
;
wl1271_debug
(
DEBUG_PSM
,
"start mac80211 PSM on hlid %d
blk
s %d "
"clean_queues %d"
,
hlid
,
wl
->
links
[
hlid
].
allocated_
blk
s
,
wl1271_debug
(
DEBUG_PSM
,
"start mac80211 PSM on hlid %d
pkt
s %d "
"clean_queues %d"
,
hlid
,
wl
->
links
[
hlid
].
allocated_
pkt
s
,
clean_queues
);
rcu_read_lock
();
...
...
drivers/net/wireless/wl12xx/reg.h
浏览文件 @
e0a8c583
...
...
@@ -296,81 +296,6 @@
===============================================*/
#define REG_EVENT_MAILBOX_PTR (SCR_PAD1)
/* Misc */
#define REG_ENABLE_TX_RX (ENABLE)
/*
* Rx configuration (filter) information element
* ---------------------------------------------
*/
#define REG_RX_CONFIG (RX_CFG)
#define REG_RX_FILTER (RX_FILTER_CFG)
#define RX_CFG_ENABLE_PHY_HEADER_PLCP 0x0002
/* promiscuous - receives all valid frames */
#define RX_CFG_PROMISCUOUS 0x0008
/* receives frames from any BSSID */
#define RX_CFG_BSSID 0x0020
/* receives frames destined to any MAC address */
#define RX_CFG_MAC 0x0010
#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC 0x0010
#define RX_CFG_ENABLE_ANY_DEST_MAC 0x0000
#define RX_CFG_ENABLE_ONLY_MY_BSSID 0x0020
#define RX_CFG_ENABLE_ANY_BSSID 0x0000
/* discards all broadcast frames */
#define RX_CFG_DISABLE_BCAST 0x0200
#define RX_CFG_ENABLE_ONLY_MY_SSID 0x0400
#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
#define RX_CFG_COPY_RX_STATUS 0x2000
#define RX_CFG_TSF 0x10000
#define RX_CONFIG_OPTION_ANY_DST_MY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
RX_CFG_ENABLE_ONLY_MY_BSSID)
#define RX_CONFIG_OPTION_MY_DST_ANY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
| RX_CFG_ENABLE_ANY_BSSID)
#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
RX_CFG_ENABLE_ANY_BSSID)
#define RX_CONFIG_OPTION_MY_DST_MY_BSS (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
| RX_CFG_ENABLE_ONLY_MY_BSSID)
#define RX_CONFIG_OPTION_FOR_SCAN (RX_CFG_ENABLE_PHY_HEADER_PLCP \
| RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
| RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
#define RX_CONFIG_OPTION_FOR_JOIN (RX_CFG_ENABLE_ONLY_MY_BSSID | \
RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
#define RX_CONFIG_OPTION_FOR_IBSS_JOIN (RX_CFG_ENABLE_ONLY_MY_SSID | \
RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
#define RX_FILTER_OPTION_DEF (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
| CFG_RX_CTL_EN | CFG_RX_BCN_EN\
| CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
#define RX_FILTER_OPTION_FILTER_ALL 0
#define RX_FILTER_OPTION_DEF_PRSP_BCN (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
| CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
#define RX_FILTER_OPTION_JOIN (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
| CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
| CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
| CFG_RX_PRSP_EN)
/*===============================================
EEPROM Read/Write Request 32bit RW
------------------------------------------
...
...
drivers/net/wireless/wl12xx/rx.c
浏览文件 @
e0a8c583
...
...
@@ -30,20 +30,28 @@
#include "rx.h"
#include "io.h"
static
u8
wl12
71_rx_get_mem_block
(
struct
wl1271_fw_common
_status
*
status
,
static
u8
wl12
xx_rx_get_mem_block
(
struct
wl12xx_fw
_status
*
status
,
u32
drv_rx_counter
)
{
return
le32_to_cpu
(
status
->
rx_pkt_descs
[
drv_rx_counter
])
&
RX_MEM_BLOCK_MASK
;
}
static
u32
wl12
71_rx_get_buf_size
(
struct
wl1271_fw_common
_status
*
status
,
static
u32
wl12
xx_rx_get_buf_size
(
struct
wl12xx_fw
_status
*
status
,
u32
drv_rx_counter
)
{
return
(
le32_to_cpu
(
status
->
rx_pkt_descs
[
drv_rx_counter
])
&
RX_BUF_SIZE_MASK
)
>>
RX_BUF_SIZE_SHIFT_DIV
;
}
static
bool
wl12xx_rx_get_unaligned
(
struct
wl12xx_fw_status
*
status
,
u32
drv_rx_counter
)
{
/* Convert the value to bool */
return
!!
(
le32_to_cpu
(
status
->
rx_pkt_descs
[
drv_rx_counter
])
&
RX_BUF_UNALIGNED_PAYLOAD
);
}
static
void
wl1271_rx_status
(
struct
wl1271
*
wl
,
struct
wl1271_rx_descriptor
*
desc
,
struct
ieee80211_rx_status
*
status
,
...
...
@@ -89,7 +97,8 @@ static void wl1271_rx_status(struct wl1271 *wl,
}
}
static
int
wl1271_rx_handle_data
(
struct
wl1271
*
wl
,
u8
*
data
,
u32
length
)
static
int
wl1271_rx_handle_data
(
struct
wl1271
*
wl
,
u8
*
data
,
u32
length
,
bool
unaligned
)
{
struct
wl1271_rx_descriptor
*
desc
;
struct
sk_buff
*
skb
;
...
...
@@ -97,6 +106,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
u8
*
buf
;
u8
beacon
=
0
;
u8
is_data
=
0
;
u8
reserved
=
unaligned
?
NET_IP_ALIGN
:
0
;
/*
* In PLT mode we seem to get frames and mac80211 warns about them,
...
...
@@ -131,17 +141,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
return
-
EINVAL
;
}
skb
=
__dev_alloc_skb
(
length
,
GFP_KERNEL
);
/* skb length not included rx descriptor */
skb
=
__dev_alloc_skb
(
length
+
reserved
-
sizeof
(
*
desc
),
GFP_KERNEL
);
if
(
!
skb
)
{
wl1271_error
(
"Couldn't allocate RX frame"
);
return
-
ENOMEM
;
}
buf
=
skb_put
(
skb
,
length
);
memcpy
(
buf
,
data
,
length
);
/* reserve the unaligned payload(if any) */
skb_reserve
(
skb
,
reserved
);
/* now we pull the descriptor out of the buffer */
skb_pull
(
skb
,
sizeof
(
*
desc
));
buf
=
skb_put
(
skb
,
length
-
sizeof
(
*
desc
));
/*
* Copy packets from aggregation buffer to the skbs without rx
* descriptor and with packet payload aligned care. In case of unaligned
* packets copy the packets in offset of 2 bytes guarantee IP header
* payload aligned to 4 bytes.
*/
memcpy
(
buf
,
data
+
sizeof
(
*
desc
),
length
-
sizeof
(
*
desc
));
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
if
(
ieee80211_is_beacon
(
hdr
->
frame_control
))
...
...
@@ -163,7 +181,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
return
is_data
;
}
void
wl12
71_rx
(
struct
wl1271
*
wl
,
struct
wl1271_fw_common
_status
*
status
)
void
wl12
xx_rx
(
struct
wl1271
*
wl
,
struct
wl12xx_fw
_status
*
status
)
{
struct
wl1271_acx_mem_map
*
wl_mem_map
=
wl
->
target_mem_map
;
u32
buf_size
;
...
...
@@ -175,12 +193,13 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
u32
pkt_offset
;
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
bool
had_data
=
false
;
bool
unaligned
=
false
;
while
(
drv_rx_counter
!=
fw_rx_counter
)
{
buf_size
=
0
;
rx_counter
=
drv_rx_counter
;
while
(
rx_counter
!=
fw_rx_counter
)
{
pkt_length
=
wl12
71
_rx_get_buf_size
(
status
,
rx_counter
);
pkt_length
=
wl12
xx
_rx_get_buf_size
(
status
,
rx_counter
);
if
(
buf_size
+
pkt_length
>
WL1271_AGGR_BUFFER_SIZE
)
break
;
buf_size
+=
pkt_length
;
...
...
@@ -199,7 +218,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
* For aggregated packets, only the first memory block
* should be retrieved. The FW takes care of the rest.
*/
mem_block
=
wl12
71
_rx_get_mem_block
(
status
,
mem_block
=
wl12
xx
_rx_get_mem_block
(
status
,
drv_rx_counter
);
wl
->
rx_mem_pool_addr
.
addr
=
(
mem_block
<<
8
)
+
...
...
@@ -220,8 +239,12 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
/* Split data into separate packets */
pkt_offset
=
0
;
while
(
pkt_offset
<
buf_size
)
{
pkt_length
=
wl12
71
_rx_get_buf_size
(
status
,
pkt_length
=
wl12
xx
_rx_get_buf_size
(
status
,
drv_rx_counter
);
unaligned
=
wl12xx_rx_get_unaligned
(
status
,
drv_rx_counter
);
/*
* the handle data call can only fail in memory-outage
* conditions, in that case the received frame will just
...
...
@@ -229,7 +252,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
*/
if
(
wl1271_rx_handle_data
(
wl
,
wl
->
aggr_buf
+
pkt_offset
,
pkt_length
)
==
1
)
pkt_length
,
unaligned
)
==
1
)
had_data
=
true
;
wl
->
rx_counter
++
;
...
...
@@ -260,14 +283,3 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
jiffies
+
msecs_to_jiffies
(
timeout
));
}
}
void
wl1271_set_default_filters
(
struct
wl1271
*
wl
)
{
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
wl
->
rx_config
=
WL1271_DEFAULT_AP_RX_CONFIG
;
wl
->
rx_filter
=
WL1271_DEFAULT_AP_RX_FILTER
;
}
else
{
wl
->
rx_config
=
WL1271_DEFAULT_STA_RX_CONFIG
;
wl
->
rx_filter
=
WL1271_DEFAULT_STA_RX_FILTER
;
}
}
drivers/net/wireless/wl12xx/rx.h
浏览文件 @
e0a8c583
...
...
@@ -86,16 +86,18 @@
* Bits 3-5 - process_id tag (AP mode FW)
* Bits 6-7 - reserved
*/
#define WL1271_RX_DESC_STATUS_MASK 0x0
7
#define WL1271_RX_DESC_STATUS_MASK 0x0
3
#define WL1271_RX_DESC_SUCCESS 0x00
#define WL1271_RX_DESC_DECRYPT_FAIL 0x01
#define WL1271_RX_DESC_MIC_FAIL 0x02
#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03
#define RX_MEM_BLOCK_MASK 0xFF
#define RX_BUF_SIZE_MASK 0xFFF00
#define RX_BUF_SIZE_SHIFT_DIV 6
#define RX_MEM_BLOCK_MASK 0xFF
#define RX_BUF_SIZE_MASK 0xFFF00
#define RX_BUF_SIZE_SHIFT_DIV 6
/* If set, the start of IP payload is not 4 bytes aligned */
#define RX_BUF_UNALIGNED_PAYLOAD BIT(20)
enum
{
WL12XX_RX_CLASS_UNKNOWN
,
...
...
@@ -119,16 +121,12 @@ struct wl1271_rx_descriptor {
u8
snr
;
__le32
timestamp
;
u8
packet_class
;
union
{
u8
process_id
;
/* STA FW */
u8
hlid
;
/* AP FW */
}
__packed
;
u8
hlid
;
u8
pad_len
;
u8
reserved
;
}
__packed
;
void
wl12
71_rx
(
struct
wl1271
*
wl
,
struct
wl1271_fw_common
_status
*
status
);
void
wl12
xx_rx
(
struct
wl1271
*
wl
,
struct
wl12xx_fw
_status
*
status
);
u8
wl1271_rate_to_idx
(
int
rate
,
enum
ieee80211_band
band
);
void
wl1271_set_default_filters
(
struct
wl1271
*
wl
);
#endif
drivers/net/wireless/wl12xx/scan.c
浏览文件 @
e0a8c583
...
...
@@ -33,6 +33,8 @@ void wl1271_scan_complete_work(struct work_struct *work)
{
struct
delayed_work
*
dwork
;
struct
wl1271
*
wl
;
int
ret
;
bool
is_sta
,
is_ibss
;
dwork
=
container_of
(
work
,
struct
delayed_work
,
work
);
wl
=
container_of
(
dwork
,
struct
wl1271
,
scan_complete_work
);
...
...
@@ -50,21 +52,34 @@ void wl1271_scan_complete_work(struct work_struct *work)
wl
->
scan
.
state
=
WL1271_SCAN_STATE_IDLE
;
memset
(
wl
->
scan
.
scanned_ch
,
0
,
sizeof
(
wl
->
scan
.
scanned_ch
));
wl
->
scan
.
req
=
NULL
;
ieee80211_scan_completed
(
wl
->
hw
,
false
);
/* restore hardware connection monitoring template */
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
{
if
(
wl1271_ps_elp_wakeup
(
wl
)
==
0
)
{
wl1271_cmd_build_ap_probe_req
(
wl
,
wl
->
probereq
);
wl1271_ps_elp_sleep
(
wl
);
}
/* restore hardware connection monitoring template */
wl1271_cmd_build_ap_probe_req
(
wl
,
wl
->
probereq
);
}
/* return to ROC if needed */
is_sta
=
(
wl
->
bss_type
==
BSS_TYPE_STA_BSS
);
is_ibss
=
(
wl
->
bss_type
==
BSS_TYPE_IBSS
);
if
((
is_sta
&&
!
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
||
(
is_ibss
&&
!
test_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
)))
{
/* restore remain on channel */
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
}
wl1271_ps_elp_sleep
(
wl
);
if
(
wl
->
scan
.
failed
)
{
wl1271_info
(
"Scan completed due to error."
);
wl12xx_queue_recovery_work
(
wl
);
}
ieee80211_scan_completed
(
wl
->
hw
,
false
);
out:
mutex_unlock
(
&
wl
->
mutex
);
...
...
@@ -156,6 +171,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
if
(
passive
||
wl
->
scan
.
req
->
n_ssids
==
0
)
scan_options
|=
WL1271_SCAN_OPT_PASSIVE
;
if
(
WARN_ON
(
wl
->
role_id
==
WL12XX_INVALID_ROLE_ID
))
{
ret
=
-
EINVAL
;
goto
out
;
}
cmd
->
params
.
role_id
=
wl
->
role_id
;
cmd
->
params
.
scan_options
=
cpu_to_le16
(
scan_options
);
cmd
->
params
.
n_ch
=
wl1271_get_scan_channels
(
wl
,
wl
->
scan
.
req
,
...
...
@@ -167,10 +187,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
}
cmd
->
params
.
tx_rate
=
cpu_to_le32
(
basic_rate
);
cmd
->
params
.
rx_config_options
=
cpu_to_le32
(
CFG_RX_ALL_GOOD
);
cmd
->
params
.
rx_filter_options
=
cpu_to_le32
(
CFG_RX_PRSP_EN
|
CFG_RX_MGMT_EN
|
CFG_RX_BCN_EN
);
cmd
->
params
.
n_probe_reqs
=
wl
->
conf
.
scan
.
num_probe_reqs
;
cmd
->
params
.
tx_rate
=
cpu_to_le32
(
basic_rate
);
cmd
->
params
.
tid_trigger
=
0
;
...
...
@@ -186,6 +202,8 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
memcpy
(
cmd
->
params
.
ssid
,
wl
->
scan
.
ssid
,
wl
->
scan
.
ssid_len
);
}
memcpy
(
cmd
->
addr
,
wl
->
mac_addr
,
ETH_ALEN
);
ret
=
wl1271_cmd_build_probe_req
(
wl
,
wl
->
scan
.
ssid
,
wl
->
scan
.
ssid_len
,
wl
->
scan
.
req
->
ie
,
wl
->
scan
.
req
->
ie_len
,
band
);
...
...
drivers/net/wireless/wl12xx/scan.h
浏览文件 @
e0a8c583
...
...
@@ -46,7 +46,10 @@ 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_PRIORITY_HIGH 4
/* scan even if we fail to enter psm */
#define WL1271_SCAN_OPT_FORCE 8
#define WL1271_SCAN_BAND_2_4_GHZ 0
#define WL1271_SCAN_BAND_5_GHZ 1
...
...
@@ -62,27 +65,27 @@ enum {
};
struct
basic_scan_params
{
__le32
rx_config_options
;
__le32
rx_filter_options
;
/* Scan option flags (WL1271_SCAN_OPT_*) */
__le16
scan_options
;
u8
role_id
;
/* Number of scan channels in the list (maximum 30) */
u8
n_ch
;
/* This field indicates the number of probe requests to send
per channel for an active scan */
u8
n_probe_reqs
;
/* Rate bit field for sending the probes */
__le32
tx_rate
;
u8
tid_trigger
;
u8
ssid_len
;
/* in order to align */
u8
padding1
[
2
];
u8
use_ssid_list
;
/* Rate bit field for sending the probes */
__le32
tx_rate
;
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
/* Band to scan */
u8
band
;
u8
use_ssid_list
;
u8
scan_tag
;
u8
padding2
;
u8
padding2
[
2
]
;
}
__packed
;
struct
basic_scan_channel_params
{
...
...
@@ -105,6 +108,10 @@ struct wl1271_cmd_scan {
struct
basic_scan_params
params
;
struct
basic_scan_channel_params
channels
[
WL1271_SCAN_MAX_CHANNELS
];
/* src mac address */
u8
addr
[
ETH_ALEN
];
u8
padding
[
2
];
}
__packed
;
struct
wl1271_cmd_trigger_scan_to
{
...
...
@@ -184,7 +191,7 @@ struct wl1271_cmd_sched_scan_config {
}
__packed
;
#define SCHED_SCAN_MAX_SSIDS
8
#define SCHED_SCAN_MAX_SSIDS
16
enum
{
SCAN_SSID_TYPE_PUBLIC
=
0
,
...
...
drivers/net/wireless/wl12xx/sdio.c
浏览文件 @
e0a8c583
...
...
@@ -412,7 +412,5 @@ module_exit(wl1271_exit);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL127
1
_FW_NAME
);
MODULE_FIRMWARE
(
WL127
X
_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_AP_FW_NAME
);
drivers/net/wireless/wl12xx/spi.c
浏览文件 @
e0a8c583
...
...
@@ -486,8 +486,6 @@ module_exit(wl1271_exit);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
MODULE_FIRMWARE
(
WL127
1
_FW_NAME
);
MODULE_FIRMWARE
(
WL127
X
_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_FW_NAME
);
MODULE_FIRMWARE
(
WL127X_AP_FW_NAME
);
MODULE_FIRMWARE
(
WL128X_AP_FW_NAME
);
MODULE_ALIAS
(
"spi:wl1271"
);
drivers/net/wireless/wl12xx/tx.c
浏览文件 @
e0a8c583
...
...
@@ -37,9 +37,10 @@ static int wl1271_set_default_wep_key(struct wl1271 *wl, u8 id)
bool
is_ap
=
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
);
if
(
is_ap
)
ret
=
wl1271_cmd_set_ap_default_wep_key
(
wl
,
id
);
ret
=
wl12xx_cmd_set_default_wep_key
(
wl
,
id
,
wl
->
ap_bcast_hlid
);
else
ret
=
wl12
71_cmd_set_sta_default_wep_key
(
wl
,
id
);
ret
=
wl12
xx_cmd_set_default_wep_key
(
wl
,
id
,
wl
->
sta_hl
id
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -77,6 +78,7 @@ static int wl1271_tx_update_filters(struct wl1271 *wl,
struct
sk_buff
*
skb
)
{
struct
ieee80211_hdr
*
hdr
;
int
ret
;
hdr
=
(
struct
ieee80211_hdr
*
)(
skb
->
data
+
sizeof
(
struct
wl1271_tx_hw_descr
));
...
...
@@ -90,9 +92,19 @@ static int wl1271_tx_update_filters(struct wl1271 *wl,
if
(
!
ieee80211_is_auth
(
hdr
->
frame_control
))
return
0
;
wl1271_configure_filters
(
wl
,
FIF_OTHER_BSS
);
if
(
wl
->
dev_hlid
!=
WL12XX_INVALID_LINK_ID
)
goto
out
;
return
wl1271_acx_rx_config
(
wl
,
wl
->
rx_config
,
wl
->
rx_filter
);
wl1271_debug
(
DEBUG_CMD
,
"starting device role for roaming"
);
ret
=
wl12xx_cmd_role_start_dev
(
wl
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
if
(
ret
<
0
)
goto
out
;
out:
return
0
;
}
static
void
wl1271_tx_ap_update_inconnection_sta
(
struct
wl1271
*
wl
,
...
...
@@ -114,24 +126,29 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
static
void
wl1271_tx_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
)
{
bool
fw_ps
;
u8
tx_
blk
s
;
u8
tx_
pkt
s
;
/* only regulate station links */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
fw_ps
=
test_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
tx_
blks
=
wl
->
links
[
hlid
].
allocated_blk
s
;
tx_
pkts
=
wl
->
links
[
hlid
].
allocated_pkt
s
;
/*
* if in FW PS and there is enough data in FW we can put the link
* into high-level PS and clean out its TX queues.
*/
if
(
fw_ps
&&
tx_
blks
>=
WL1271_PS_STA_MAX_BLOCK
S
)
if
(
fw_ps
&&
tx_
pkts
>=
WL1271_PS_STA_MAX_PACKET
S
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
u8
wl1271_tx_get_hlid
(
struct
sk_buff
*
skb
)
static
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
return
wl
->
dummy_packet
==
skb
;
}
u8
wl12xx_tx_get_hlid_ap
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_tx_info
*
control
=
IEEE80211_SKB_CB
(
skb
);
...
...
@@ -144,14 +161,32 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb)
}
else
{
struct
ieee80211_hdr
*
hdr
;
if
(
!
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
return
wl
->
system_hlid
;
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
if
(
ieee80211_is_mgmt
(
hdr
->
frame_control
))
return
WL1271_AP_GLOBAL_HLID
;
return
wl
->
ap_global_hlid
;
else
return
WL1271_AP_BROADCAST_HLID
;
return
wl
->
ap_bcast_hlid
;
}
}
static
u8
wl1271_tx_get_hlid
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
if
(
wl12xx_is_dummy_packet
(
wl
,
skb
))
return
wl
->
system_hlid
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
return
wl12xx_tx_get_hlid_ap
(
wl
,
skb
);
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
)
||
test_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
))
return
wl
->
sta_hlid
;
else
return
wl
->
dev_hlid
;
}
static
unsigned
int
wl12xx_calc_packet_alignment
(
struct
wl1271
*
wl
,
unsigned
int
packet_length
)
{
...
...
@@ -169,12 +204,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
u32
len
;
u32
total_blocks
;
int
id
,
ret
=
-
EBUSY
,
ac
;
u32
spare_blocks
;
if
(
unlikely
(
wl
->
quirks
&
WL12XX_QUIRK_USE_2_SPARE_BLOCKS
))
spare_blocks
=
2
;
else
spare_blocks
=
1
;
/* we use 1 spare block */
u32
spare_blocks
=
1
;
if
(
buf_offset
+
total_len
>
WL1271_AGGR_BUFFER_SIZE
)
return
-
EAGAIN
;
...
...
@@ -206,12 +238,14 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
desc
->
id
=
id
;
wl
->
tx_blocks_available
-=
total_blocks
;
wl
->
tx_allocated_blocks
+=
total_blocks
;
ac
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
skb
));
wl
->
tx_allocated_
blocks
[
ac
]
+=
total_blocks
;
wl
->
tx_allocated_
pkts
[
ac
]
++
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
wl
->
links
[
hlid
].
allocated_blks
+=
total_blocks
;
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
&&
hlid
>=
WL1271_AP_STA_HLID_START
)
wl
->
links
[
hlid
].
allocated_pkts
++
;
ret
=
0
;
...
...
@@ -225,11 +259,6 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
return
ret
;
}
static
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
return
wl
->
dummy_packet
==
skb
;
}
static
void
wl1271_tx_fill_hdr
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
,
u32
extra
,
struct
ieee80211_tx_info
*
control
,
u8
hlid
)
...
...
@@ -280,9 +309,9 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
wl
->
session_counter
<<
TX_HW_ATTR_OFST_SESSION_COUNTER
;
}
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
{
desc
->
aid
=
hlid
;
desc
->
hlid
=
hlid
;
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
{
/* if the packets are destined for AP (have a STA entry)
send them with AP rate policies, otherwise use default
basic rates */
...
...
@@ -291,18 +320,12 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
else
rate_idx
=
ACX_TX_BASIC_RATE
;
}
else
{
desc
->
hlid
=
hlid
;
switch
(
hlid
)
{
case
WL1271_AP_GLOBAL_HLID
:
if
(
hlid
==
wl
->
ap_global_hlid
)
rate_idx
=
ACX_TX_AP_MODE_MGMT_RATE
;
break
;
case
WL1271_AP_BROADCAST_HLID
:
else
if
(
hlid
==
wl
->
ap_bcast_hlid
)
rate_idx
=
ACX_TX_AP_MODE_BCST_RATE
;
break
;
default:
else
rate_idx
=
ac
;
break
;
}
}
tx_attr
|=
rate_idx
<<
TX_HW_ATTR_OFST_RATE_POLICY
;
...
...
@@ -376,10 +399,11 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
}
}
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
hlid
=
wl1271_tx_get_hlid
(
skb
);
else
hlid
=
TX_HW_DEFAULT_AID
;
hlid
=
wl1271_tx_get_hlid
(
wl
,
skb
);
if
(
hlid
==
WL12XX_INVALID_LINK_ID
)
{
wl1271_error
(
"invalid hlid. dropping skb 0x%p"
,
skb
);
return
-
EINVAL
;
}
ret
=
wl1271_tx_allocate
(
wl
,
skb
,
extra
,
buf_offset
,
hlid
);
if
(
ret
<
0
)
...
...
@@ -462,20 +486,24 @@ void wl1271_handle_tx_low_watermark(struct wl1271 *wl)
static
struct
sk_buff_head
*
wl1271_select_queue
(
struct
wl1271
*
wl
,
struct
sk_buff_head
*
queues
)
{
int
i
,
q
=
-
1
;
u32
min_
blk
s
=
0xffffffff
;
int
i
,
q
=
-
1
,
ac
;
u32
min_
pkt
s
=
0xffffffff
;
/*
* Find a non-empty ac where:
* 1. There are packets to transmit
* 2. The FW has the least allocated blocks
*
* We prioritize the ACs according to VO>VI>BE>BK
*/
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
if
(
!
skb_queue_empty
(
&
queues
[
i
])
&&
(
wl
->
tx_allocated_blocks
[
i
]
<
min_blks
))
{
q
=
i
;
min_blks
=
wl
->
tx_allocated_blocks
[
q
];
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
ac
=
wl1271_tx_get_queue
(
i
);
if
(
!
skb_queue_empty
(
&
queues
[
ac
])
&&
(
wl
->
tx_allocated_pkts
[
ac
]
<
min_pkts
))
{
q
=
ac
;
min_pkts
=
wl
->
tx_allocated_pkts
[
q
];
}
}
if
(
q
==
-
1
)
return
NULL
;
...
...
@@ -579,7 +607,7 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
if
(
wl12xx_is_dummy_packet
(
wl
,
skb
))
{
set_bit
(
WL1271_FLAG_DUMMY_PACKET_PENDING
,
&
wl
->
flags
);
}
else
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
u8
hlid
=
wl1271_tx_get_hlid
(
skb
);
u8
hlid
=
wl1271_tx_get_hlid
(
wl
,
skb
);
skb_queue_head
(
&
wl
->
links
[
hlid
].
tx_queue
[
q
],
skb
);
/* make sure we dequeue the same packet next time */
...
...
@@ -826,10 +854,14 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
total
[
i
]
=
0
;
while
((
skb
=
skb_dequeue
(
&
wl
->
links
[
hlid
].
tx_queue
[
i
])))
{
wl1271_debug
(
DEBUG_TX
,
"link freeing skb 0x%p"
,
skb
);
info
=
IEEE80211_SKB_CB
(
skb
);
info
->
status
.
rates
[
0
].
idx
=
-
1
;
info
->
status
.
rates
[
0
].
count
=
0
;
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
if
(
!
wl12xx_is_dummy_packet
(
wl
,
skb
))
{
info
=
IEEE80211_SKB_CB
(
skb
);
info
->
status
.
rates
[
0
].
idx
=
-
1
;
info
->
status
.
rates
[
0
].
count
=
0
;
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
}
total
[
i
]
++
;
}
}
...
...
@@ -853,8 +885,8 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
for
(
i
=
0
;
i
<
AP_MAX_LINKS
;
i
++
)
{
wl1271_tx_reset_link_queues
(
wl
,
i
);
wl
->
links
[
i
].
allocated_
blk
s
=
0
;
wl
->
links
[
i
].
prev_freed_
blk
s
=
0
;
wl
->
links
[
i
].
allocated_
pkt
s
=
0
;
wl
->
links
[
i
].
prev_freed_
pkt
s
=
0
;
}
wl
->
last_tx_hlid
=
0
;
...
...
drivers/net/wireless/wl12xx/tx.h
浏览文件 @
e0a8c583
...
...
@@ -29,9 +29,6 @@
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
/* The chipset reference driver states, that the "aid" value 1
* is for infra-BSS, but is still always used */
#define TX_HW_DEFAULT_AID 1
#define TX_HW_ATTR_SAVE_RETRIES BIT(0)
#define TX_HW_ATTR_HEADER_PAD BIT(1)
...
...
@@ -116,12 +113,8 @@ struct wl1271_tx_hw_descr {
u8
id
;
/* The packet TID value (as User-Priority) */
u8
tid
;
union
{
/* STA - Identifier of the remote STA in IBSS, 1 in infra-BSS */
u8
aid
;
/* AP - host link ID (HLID) */
u8
hlid
;
}
__packed
;
/* host link ID (HLID) */
u8
hlid
;
u8
reserved
;
}
__packed
;
...
...
@@ -133,7 +126,8 @@ enum wl1271_tx_hw_res_status {
TX_TIMEOUT
=
4
,
TX_KEY_NOT_FOUND
=
5
,
TX_PEER_NOT_FOUND
=
6
,
TX_SESSION_MISMATCH
=
7
TX_SESSION_MISMATCH
=
7
,
TX_LINK_NOT_VALID
=
8
,
};
struct
wl1271_tx_hw_res_descr
{
...
...
@@ -216,7 +210,7 @@ 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
);
u32
wl1271_tx_min_rate_get
(
struct
wl1271
*
wl
);
u8
wl12
71_tx_get_hlid
(
struct
sk_buff
*
skb
);
u8
wl12
xx_tx_get_hlid_ap
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
);
void
wl1271_tx_reset_link_queues
(
struct
wl1271
*
wl
,
u8
hlid
);
void
wl1271_handle_tx_low_watermark
(
struct
wl1271
*
wl
);
...
...
drivers/net/wireless/wl12xx/wl12xx.h
浏览文件 @
e0a8c583
...
...
@@ -112,28 +112,8 @@ extern u32 wl12xx_debug_level;
true); \
} while (0)
#define WL1271_DEFAULT_STA_RX_CONFIG (CFG_UNI_FILTER_EN | \
CFG_BSSID_FILTER_EN | \
CFG_MC_FILTER_EN)
#define WL1271_DEFAULT_STA_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN | \
CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \
CFG_RX_CTL_EN | CFG_RX_BCN_EN | \
CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
#define WL1271_DEFAULT_AP_RX_CONFIG 0
#define WL1271_DEFAULT_AP_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PREQ_EN | \
CFG_RX_MGMT_EN | CFG_RX_DATA_EN | \
CFG_RX_CTL_EN | CFG_RX_AUTH_EN | \
CFG_RX_ASSOC_EN)
#define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin"
#define WL128X_FW_NAME "ti-connectivity/wl128x-fw.bin"
#define WL127X_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin"
#define WL128X_AP_FW_NAME "ti-connectivity/wl128x-fw-ap.bin"
#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin"
#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin"
/*
* wl127x and wl128x are using the same NVS file name. However, the
...
...
@@ -157,25 +137,34 @@ extern u32 wl12xx_debug_level;
#define WL1271_DEFAULT_BEACON_INT 100
#define WL1271_DEFAULT_DTIM_PERIOD 1
#define WL1271_AP_GLOBAL_HLID 0
#define WL1271_AP_BROADCAST_HLID 1
#define WL1271_AP_STA_HLID_START 2
#define WL12XX_MAX_ROLES 4
#define WL12XX_MAX_LINKS 8
#define WL12XX_INVALID_ROLE_ID 0xff
#define WL12XX_INVALID_LINK_ID 0xff
/* Defined by FW as 0. Will not be freed or allocated. */
#define WL12XX_SYSTEM_HLID 0
/*
* TODO: we currently don't support multirole. remove
* this constant from the code when we do.
*/
#define WL1271_AP_STA_HLID_START 3
/*
* When in AP-mode, we allow (at least) this number of
mem-block
s
* When in AP-mode, we allow (at least) this number of
packet
s
* to be transmitted to FW for a STA in PS-mode. Only when packets are
* present in the FW buffers it will wake the sleeping STA. We want to put
* enough packets for the driver to transmit all of its buffered data before
* the STA goes to sleep again. But we don't want to take too much mem
-blocks
* the STA goes to sleep again. But we don't want to take too much mem
ory
* as it might hurt the throughput of active STAs.
* The number of blocks (18) is enough for 2 large packets.
*/
#define WL1271_PS_STA_MAX_
BLOCKS (2 * 9)
#define WL1271_PS_STA_MAX_
PACKETS 2
#define WL1271_AP_BSS_INDEX 0
#define WL1271_AP_DEF_BEACON_EXP 20
#define ACX_TX_DESCRIPTORS
32
#define ACX_TX_DESCRIPTORS
16
#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
...
...
@@ -247,26 +236,22 @@ struct wl1271_stats {
#define AP_MAX_STATIONS 5
/* Broadcast and Global links + links to stations */
#define AP_MAX_LINKS (AP_MAX_STATIONS + 2)
/* Broadcast and Global links + system link + links to stations */
/*
* TODO: when WL1271_AP_STA_HLID_START is no longer constant, change all
* the places that use this.
*/
#define AP_MAX_LINKS (AP_MAX_STATIONS + 3)
/* FW status registers
common for AP/STA
*/
struct
wl12
71_fw_common
_status
{
/* FW status registers */
struct
wl12
xx_fw
_status
{
__le32
intr
;
u8
fw_rx_counter
;
u8
drv_rx_counter
;
u8
reserved
;
u8
tx_results_counter
;
__le32
rx_pkt_descs
[
NUM_RX_PKT_DESC
];
__le32
tx_released_blks
[
NUM_TX_QUEUES
];
__le32
fw_localtime
;
}
__packed
;
/* FW status registers for AP */
struct
wl1271_fw_ap_status
{
struct
wl1271_fw_common_status
common
;
/* Next fields valid only in AP FW */
/*
* A bitmap (where each bit represents a single HLID)
...
...
@@ -274,29 +259,29 @@ struct wl1271_fw_ap_status {
*/
__le32
link_ps_bitmap
;
/* Number of freed MBs per HLID */
u8
tx_lnk_free_blks
[
AP_MAX_LINKS
];
u8
padding_1
[
1
];
}
__packed
;
/*
* A bitmap (where each bit represents a single HLID) to indicate
* if the station is in Fast mode
*/
__le32
link_fast_bitmap
;
/* FW status registers for STA */
struct
wl1271_fw_sta_status
{
struct
wl1271_fw_common_status
common
;
/* Cumulative counter of total released mem blocks since FW-reset */
__le32
total_released_blks
;
u8
tx_total
;
u8
reserved1
;
__le16
reserved2
;
__le32
log_start_addr
;
}
__packed
;
/* Size (in Memory Blocks) of TX pool */
__le32
tx_total
;
struct
wl1271_fw_full_status
{
union
{
struct
wl1271_fw_common_status
common
;
struct
wl1271_fw_sta_status
sta
;
struct
wl1271_fw_ap_status
ap
;
};
}
__packed
;
/* Cumulative counter of released packets per AC */
u8
tx_released_pkts
[
NUM_TX_QUEUES
];
/* Cumulative counter of freed packets per HLID */
u8
tx_lnk_free_pkts
[
WL12XX_MAX_LINKS
];
/* Cumulative counter of released Voice memory blocks */
u8
tx_voice_released_blks
;
u8
padding_1
[
7
];
__le32
log_start_addr
;
}
__packed
;
struct
wl1271_rx_mem_pool_addr
{
u32
addr
;
...
...
@@ -342,7 +327,7 @@ struct wl1271_ap_key {
enum
wl12xx_flags
{
WL1271_FLAG_STA_ASSOCIATED
,
WL1271_FLAG_JOINED
,
WL1271_FLAG_
IBSS_
JOINED
,
WL1271_FLAG_GPIO_POWER
,
WL1271_FLAG_TX_QUEUE_STOPPED
,
WL1271_FLAG_TX_PENDING
,
...
...
@@ -369,11 +354,14 @@ struct wl1271_link {
/* AP-mode - TX queue per AC in link */
struct
sk_buff_head
tx_queue
[
NUM_TX_QUEUES
];
/* accounting for allocated /
available TX block
s in FW */
u8
allocated_
blk
s
;
u8
prev_freed_
blk
s
;
/* accounting for allocated /
freed packet
s in FW */
u8
allocated_
pkt
s
;
u8
prev_freed_
pkt
s
;
u8
addr
[
ETH_ALEN
];
/* bitmap of TIDs where RX BA sessions are active for this link */
u8
ba_bitmap
;
};
struct
wl1271
{
...
...
@@ -405,7 +393,6 @@ struct wl1271 {
u8
*
fw
;
size_t
fw_len
;
u8
fw_bss_type
;
void
*
nvs
;
size_t
nvs_len
;
...
...
@@ -418,15 +405,30 @@ struct wl1271 {
u8
ssid
[
IEEE80211_MAX_SSID_LEN
+
1
];
u8
ssid_len
;
int
channel
;
u8
role_id
;
u8
dev_role_id
;
u8
system_hlid
;
u8
sta_hlid
;
u8
dev_hlid
;
u8
ap_global_hlid
;
u8
ap_bcast_hlid
;
unsigned
long
links_map
[
BITS_TO_LONGS
(
WL12XX_MAX_LINKS
)];
unsigned
long
roles_map
[
BITS_TO_LONGS
(
WL12XX_MAX_ROLES
)];
unsigned
long
roc_map
[
BITS_TO_LONGS
(
WL12XX_MAX_ROLES
)];
struct
wl1271_acx_mem_map
*
target_mem_map
;
/* Accounting for allocated / available TX blocks on HW */
u32
tx_blocks_freed
[
NUM_TX_QUEUES
]
;
u32
tx_blocks_freed
;
u32
tx_blocks_available
;
u32
tx_allocated_blocks
[
NUM_TX_QUEUES
]
;
u32
tx_allocated_blocks
;
u32
tx_results_count
;
/* Accounting for allocated / available Tx packets in HW */
u32
tx_pkts_freed
[
NUM_TX_QUEUES
];
u32
tx_allocated_pkts
[
NUM_TX_QUEUES
];
/* Transmitted TX packets counter for chipset interface */
u32
tx_packets_count
;
...
...
@@ -535,10 +537,6 @@ struct wl1271 {
struct
work_struct
rx_streaming_disable_work
;
struct
timer_list
rx_streaming_timer
;
unsigned
int
filters
;
unsigned
int
rx_config
;
unsigned
int
rx_filter
;
struct
completion
*
elp_compl
;
struct
completion
*
ps_compl
;
struct
delayed_work
elp_work
;
...
...
@@ -562,7 +560,7 @@ struct wl1271 {
u32
buffer_cmd
;
u32
buffer_busyword
[
WL1271_BUSY_WORD_CNT
];
struct
wl12
71_fw_full
_status
*
fw_status
;
struct
wl12
xx_fw
_status
*
fw_status
;
struct
wl1271_tx_hw_res_if
*
tx_res_if
;
struct
ieee80211_vif
*
vif
;
...
...
@@ -622,6 +620,9 @@ struct wl1271 {
/* Platform limitations */
unsigned
int
platform_quirks
;
/* number of currently active RX BA sessions */
int
ba_rx_session_count
;
};
struct
wl1271_station
{
...
...
@@ -659,12 +660,6 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
/* Each RX/TX transaction requires an end-of-transaction transfer */
#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
/*
* Older firmwares use 2 spare TX blocks
* (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
*/
#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
/* WL128X requires aggregated packets to be aligned to the SDIO block size */
#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
...
...
drivers/net/wireless/wl12xx/wl12xx_80211.h
浏览文件 @
e0a8c583
...
...
@@ -105,18 +105,6 @@ struct wl12xx_ie_country {
/* Templates */
struct
wl12xx_beacon_template
{
struct
ieee80211_header
header
;
__le32
time_stamp
[
2
];
__le16
beacon_interval
;
__le16
capability
;
struct
wl12xx_ie_ssid
ssid
;
struct
wl12xx_ie_rates
rates
;
struct
wl12xx_ie_rates
ext_rates
;
struct
wl12xx_ie_ds_params
ds_params
;
struct
wl12xx_ie_country
country
;
}
__packed
;
struct
wl12xx_null_data_template
{
struct
ieee80211_header
header
;
}
__packed
;
...
...
@@ -146,19 +134,6 @@ struct wl12xx_arp_rsp_template {
__be32
target_ip
;
}
__packed
;
struct
wl12xx_probe_resp_template
{
struct
ieee80211_header
header
;
__le32
time_stamp
[
2
];
__le16
beacon_interval
;
__le16
capability
;
struct
wl12xx_ie_ssid
ssid
;
struct
wl12xx_ie_rates
rates
;
struct
wl12xx_ie_rates
ext_rates
;
struct
wl12xx_ie_ds_params
ds_params
;
struct
wl12xx_ie_country
country
;
}
__packed
;
struct
wl12xx_disconn_template
{
struct
ieee80211_header
header
;
__le16
disconn_reason
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录