Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
376cf5d3
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
376cf5d3
编写于
9月 19, 2011
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://github.com/lucacoelho/wl12xx
上级
12e62d6f
045c745f
变更
16
显示空白变更内容
内联
并排
Showing
16 changed file
with
358 addition
and
158 deletion
+358
-158
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/Kconfig
+0
-10
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.c
+40
-0
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/acx.h
+18
-0
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.c
+11
-6
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/cmd.h
+7
-0
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/conf.h
+15
-8
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/debugfs.c
+47
-41
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.c
+23
-14
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.c
+5
-0
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/main.c
+71
-25
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/ps.c
+6
-2
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/rx.c
+5
-4
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/scan.c
+84
-40
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.c
+16
-6
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/tx.h
+4
-0
drivers/net/wireless/wl12xx/wl12xx.h
drivers/net/wireless/wl12xx/wl12xx.h
+6
-2
未找到文件。
drivers/net/wireless/wl12xx/Kconfig
浏览文件 @
376cf5d3
...
...
@@ -19,16 +19,6 @@ config WL12XX
If you choose to build a module, it will be called wl12xx. Say N if
unsure.
config WL12XX_HT
bool "TI wl12xx 802.11 HT support (EXPERIMENTAL)"
depends on WL12XX && EXPERIMENTAL
default n
---help---
This will enable 802.11 HT support in the wl12xx module.
That configuration is temporary due to the code incomplete and
still in testing process.
config WL12XX_SPI
tristate "TI wl12xx SPI support"
depends on WL12XX && SPI_MASTER
...
...
drivers/net/wireless/wl12xx/acx.c
浏览文件 @
376cf5d3
...
...
@@ -1691,3 +1691,43 @@ int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl)
kfree
(
acx
);
return
ret
;
}
int
wl12xx_acx_config_hangover
(
struct
wl1271
*
wl
)
{
struct
wl12xx_acx_config_hangover
*
acx
;
struct
conf_hangover_settings
*
conf
=
&
wl
->
conf
.
hangover
;
int
ret
;
wl1271_debug
(
DEBUG_ACX
,
"acx config hangover"
);
acx
=
kzalloc
(
sizeof
(
*
acx
),
GFP_KERNEL
);
if
(
!
acx
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
acx
->
recover_time
=
cpu_to_le32
(
conf
->
recover_time
);
acx
->
hangover_period
=
conf
->
hangover_period
;
acx
->
dynamic_mode
=
conf
->
dynamic_mode
;
acx
->
early_termination_mode
=
conf
->
early_termination_mode
;
acx
->
max_period
=
conf
->
max_period
;
acx
->
min_period
=
conf
->
min_period
;
acx
->
increase_delta
=
conf
->
increase_delta
;
acx
->
decrease_delta
=
conf
->
decrease_delta
;
acx
->
quiet_time
=
conf
->
quiet_time
;
acx
->
increase_time
=
conf
->
increase_time
;
acx
->
window_size
=
acx
->
window_size
;
ret
=
wl1271_cmd_configure
(
wl
,
ACX_CONFIG_HANGOVER
,
acx
,
sizeof
(
*
acx
));
if
(
ret
<
0
)
{
wl1271_warning
(
"acx config hangover failed: %d"
,
ret
);
goto
out
;
}
out:
kfree
(
acx
);
return
ret
;
}
drivers/net/wireless/wl12xx/acx.h
浏览文件 @
376cf5d3
...
...
@@ -1144,6 +1144,23 @@ struct wl12xx_acx_set_rate_mgmt_params {
u8
padding2
[
2
];
}
__packed
;
struct
wl12xx_acx_config_hangover
{
struct
acx_header
header
;
__le32
recover_time
;
u8
hangover_period
;
u8
dynamic_mode
;
u8
early_termination_mode
;
u8
max_period
;
u8
min_period
;
u8
increase_delta
;
u8
decrease_delta
;
u8
quiet_time
;
u8
increase_time
;
u8
window_size
;
u8
padding
[
2
];
}
__packed
;
enum
{
ACX_WAKE_UP_CONDITIONS
=
0x0002
,
ACX_MEM_CFG
=
0x0003
,
...
...
@@ -1281,5 +1298,6 @@ int wl1271_acx_config_ps(struct wl1271 *wl);
int
wl1271_acx_set_inconnection_sta
(
struct
wl1271
*
wl
,
u8
*
addr
);
int
wl1271_acx_fm_coex
(
struct
wl1271
*
wl
);
int
wl12xx_acx_set_rate_mgmt_params
(
struct
wl1271
*
wl
);
int
wl12xx_acx_config_hangover
(
struct
wl1271
*
wl
);
#endif
/* __WL1271_ACX_H__ */
drivers/net/wireless/wl12xx/cmd.c
浏览文件 @
376cf5d3
...
...
@@ -895,7 +895,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
struct
acx_header
*
acx
=
buf
;
int
ret
;
wl1271_debug
(
DEBUG_CMD
,
"cmd configure
"
);
wl1271_debug
(
DEBUG_CMD
,
"cmd configure
(%d)"
,
id
);
acx
->
id
=
cpu_to_le16
(
id
);
...
...
@@ -1413,7 +1413,7 @@ int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
int
wl12xx_cmd_add_peer
(
struct
wl1271
*
wl
,
struct
ieee80211_sta
*
sta
,
u8
hlid
)
{
struct
wl12xx_cmd_add_peer
*
cmd
;
int
ret
;
int
i
,
ret
;
u32
sta_rates
;
wl1271_debug
(
DEBUG_CMD
,
"cmd add peer %d"
,
(
int
)
hlid
);
...
...
@@ -1424,15 +1424,19 @@ int wl12xx_cmd_add_peer(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
->
sp_len
=
sta
->
max_sp
;
cmd
->
wmm
=
sta
->
wme
?
1
:
0
;
for
(
i
=
0
;
i
<
NUM_ACCESS_CATEGORIES_COPY
;
i
++
)
if
(
sta
->
wme
&&
(
sta
->
uapsd_queues
&
BIT
(
i
)))
cmd
->
psd_type
[
i
]
=
WL1271_PSD_UPSD_TRIGGER
;
else
cmd
->
psd_type
[
i
]
=
WL1271_PSD_LEGACY
;
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
;
...
...
@@ -1440,7 +1444,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
cmd
->
supported_rates
=
cpu_to_le32
(
wl1271_tx_enabled_rates_get
(
wl
,
sta_rates
));
wl1271_debug
(
DEBUG_CMD
,
"new peer rates: 0x%x"
,
cmd
->
supported_rates
);
wl1271_debug
(
DEBUG_CMD
,
"new peer rates=0x%x queues=0x%x"
,
cmd
->
supported_rates
,
sta
->
uapsd_queues
);
ret
=
wl1271_cmd_send
(
wl
,
CMD_ADD_PEER
,
cmd
,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
...
...
drivers/net/wireless/wl12xx/cmd.h
浏览文件 @
376cf5d3
...
...
@@ -591,6 +591,13 @@ enum wl12xx_ssid_type {
WL12XX_SSID_TYPE_ANY
=
2
,
};
enum
wl1271_psd_type
{
WL1271_PSD_LEGACY
=
0
,
WL1271_PSD_UPSD_TRIGGER
=
1
,
WL1271_PSD_LEGACY_PSPOLL
=
2
,
WL1271_PSD_SAPSD
=
3
};
struct
wl12xx_cmd_add_peer
{
struct
wl1271_cmd_header
header
;
...
...
drivers/net/wireless/wl12xx/conf.h
浏览文件 @
376cf5d3
...
...
@@ -915,14 +915,6 @@ struct conf_conn_settings {
*/
u8
psm_entry_nullfunc_retries
;
/*
* Specifies the time to linger in active mode after successfully
* transmitting the PSM entry null-func frame.
*
* Range 0 - 255 TU's
*/
u8
psm_entry_hangover_period
;
/*
*
* Specifies the interval of the connection keep-alive null-func
...
...
@@ -1236,6 +1228,20 @@ struct conf_rate_policy_settings {
u8
rate_retry_policy
[
ACX_RATE_MGMT_NUM_OF_RATES
];
};
struct
conf_hangover_settings
{
u32
recover_time
;
u8
hangover_period
;
u8
dynamic_mode
;
u8
early_termination_mode
;
u8
max_period
;
u8
min_period
;
u8
increase_delta
;
u8
decrease_delta
;
u8
quiet_time
;
u8
increase_time
;
u8
window_size
;
};
struct
conf_drv_settings
{
struct
conf_sg_settings
sg
;
struct
conf_rx_settings
rx
;
...
...
@@ -1254,6 +1260,7 @@ struct conf_drv_settings {
struct
conf_rx_streaming_settings
rx_streaming
;
struct
conf_fwlog
fwlog
;
struct
conf_rate_policy_settings
rate
;
struct
conf_hangover_settings
hangover
;
u8
hci_io_ds
;
};
...
...
drivers/net/wireless/wl12xx/debugfs.c
浏览文件 @
376cf5d3
...
...
@@ -265,18 +265,10 @@ static ssize_t gpio_power_write(struct file *file,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
{
return
-
EFAULT
;
}
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in gpio_power"
);
return
-
EINVAL
;
...
...
@@ -427,17 +419,10 @@ static ssize_t dtim_interval_write(struct file *file,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for dtim_interval"
);
return
-
EINVAL
;
...
...
@@ -492,17 +477,10 @@ static ssize_t beacon_interval_write(struct file *file,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for beacon_interval"
);
return
-
EINVAL
;
...
...
@@ -542,17 +520,10 @@ static ssize_t rx_streaming_interval_write(struct file *file,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in rx_streaming_interval!"
);
return
-
EINVAL
;
...
...
@@ -601,17 +572,10 @@ static ssize_t rx_streaming_always_write(struct file *file,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
10
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value in rx_streaming_write!"
);
return
-
EINVAL
;
...
...
@@ -655,6 +619,47 @@ static const struct file_operations rx_streaming_always_ops = {
.
llseek
=
default_llseek
,
};
static
ssize_t
beacon_filtering_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
wl1271
*
wl
=
file
->
private_data
;
char
buf
[
10
];
size_t
len
;
unsigned
long
value
;
int
ret
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
ret
=
kstrtoul
(
buf
,
0
,
&
value
);
if
(
ret
<
0
)
{
wl1271_warning
(
"illegal value for beacon_filtering!"
);
return
-
EINVAL
;
}
mutex_lock
(
&
wl
->
mutex
);
ret
=
wl1271_ps_elp_wakeup
(
wl
);
if
(
ret
<
0
)
goto
out
;
ret
=
wl1271_acx_beacon_filter_opt
(
wl
,
!!
value
);
wl1271_ps_elp_sleep
(
wl
);
out:
mutex_unlock
(
&
wl
->
mutex
);
return
count
;
}
static
const
struct
file_operations
beacon_filtering_ops
=
{
.
write
=
beacon_filtering_write
,
.
open
=
wl1271_open_file_generic
,
.
llseek
=
default_llseek
,
};
static
int
wl1271_debugfs_add_files
(
struct
wl1271
*
wl
,
struct
dentry
*
rootdir
)
{
...
...
@@ -767,6 +772,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD
(
driver_state
,
rootdir
);
DEBUGFS_ADD
(
dtim_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_interval
,
rootdir
);
DEBUGFS_ADD
(
beacon_filtering
,
rootdir
);
streaming
=
debugfs_create_dir
(
"rx_streaming"
,
rootdir
);
if
(
!
streaming
||
IS_ERR
(
streaming
))
...
...
drivers/net/wireless/wl12xx/event.c
浏览文件 @
376cf5d3
...
...
@@ -171,19 +171,26 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl,
wl
->
last_rssi_event
=
event
;
}
static
void
wl1271_stop_ba_event
(
struct
wl1271
*
wl
,
u8
ba_allowed
)
static
void
wl1271_stop_ba_event
(
struct
wl1271
*
wl
)
{
/* Convert the value to bool */
wl
->
ba_allowed
=
!!
ba_allowed
;
/*
* Return in case:
* there are not BA open or the event indication is to allowed BA
*/
if
((
!
wl
->
ba_rx_bitmap
)
||
(
wl
->
ba_allowed
))
if
(
wl
->
bss_type
!=
BSS_TYPE_AP_BSS
)
{
if
(
!
wl
->
ba_rx_bitmap
)
return
;
ieee80211_stop_rx_ba_session
(
wl
->
vif
,
wl
->
ba_rx_bitmap
,
wl
->
bssid
);
}
else
{
int
i
;
struct
wl1271_link
*
lnk
;
for
(
i
=
WL1271_AP_STA_HLID_START
;
i
<
WL12XX_MAX_LINKS
;
i
++
)
{
lnk
=
&
wl
->
links
[
i
];
if
(
!
wl1271_is_active_sta
(
wl
,
i
)
||
!
lnk
->
ba_bitmap
)
continue
;
ieee80211_stop_rx_ba_session
(
wl
->
vif
,
wl
->
ba_rx_bitmap
,
wl
->
bssid
);
ieee80211_stop_rx_ba_session
(
wl
->
vif
,
lnk
->
ba_bitmap
,
lnk
->
addr
);
}
}
}
static
void
wl12xx_event_soft_gemini_sense
(
struct
wl1271
*
wl
,
...
...
@@ -283,12 +290,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_event_rssi_trigger
(
wl
,
mbox
);
}
if
((
vector
&
BA_SESSION_RX_CONSTRAINT_EVENT_ID
)
&&
!
is_ap
)
{
if
((
vector
&
BA_SESSION_RX_CONSTRAINT_EVENT_ID
))
{
wl1271_debug
(
DEBUG_EVENT
,
"BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
"ba_allowed = 0x%x"
,
mbox
->
rx_ba_allowed
);
if
(
wl
->
vif
)
wl1271_stop_ba_event
(
wl
,
mbox
->
rx_ba_allowed
);
wl
->
ba_allowed
=
!!
mbox
->
rx_ba_allowed
;
if
(
wl
->
vif
&&
!
wl
->
ba_allowed
)
wl1271_stop_ba_event
(
wl
);
}
if
((
vector
&
DUMMY_PACKET_EVENT_ID
))
{
...
...
drivers/net/wireless/wl12xx/init.c
浏览文件 @
376cf5d3
...
...
@@ -707,6 +707,11 @@ int wl1271_hw_init(struct wl1271 *wl)
if
(
ret
<
0
)
goto
out_free_memmap
;
/* configure hangover */
ret
=
wl12xx_acx_config_hangover
(
wl
);
if
(
ret
<
0
)
goto
out_free_memmap
;
return
0
;
out_free_memmap:
...
...
drivers/net/wireless/wl12xx/main.c
浏览文件 @
376cf5d3
...
...
@@ -239,7 +239,6 @@ static struct conf_drv_settings default_conf = {
.
psm_entry_retries
=
8
,
.
psm_exit_retries
=
16
,
.
psm_entry_nullfunc_retries
=
3
,
.
psm_entry_hangover_period
=
1
,
.
keep_alive_interval
=
55000
,
.
max_listen_interval
=
20
,
},
...
...
@@ -267,8 +266,8 @@ static struct conf_drv_settings default_conf = {
},
.
sched_scan
=
{
/* sched_scan requires dwell times in TU instead of TU/1000 */
.
min_dwell_time_active
=
8
,
.
max_dwell_time_active
=
3
0
,
.
min_dwell_time_active
=
30
,
.
max_dwell_time_active
=
6
0
,
.
dwell_time_passive
=
100
,
.
dwell_time_dfs
=
150
,
.
num_probe_reqs
=
2
,
...
...
@@ -359,9 +358,23 @@ static struct conf_drv_settings default_conf = {
0x00
,
0x00
,
0x00
,
},
},
.
hangover
=
{
.
recover_time
=
0
,
.
hangover_period
=
20
,
.
dynamic_mode
=
1
,
.
early_termination_mode
=
1
,
.
max_period
=
20
,
.
min_period
=
1
,
.
increase_delta
=
1
,
.
decrease_delta
=
2
,
.
quiet_time
=
4
,
.
increase_time
=
1
,
.
window_size
=
16
,
},
};
static
char
*
fwlog_param
;
static
bool
bug_on_recovery
;
static
void
__wl1271_op_remove_interface
(
struct
wl1271
*
wl
,
bool
reset_tx_queues
);
...
...
@@ -757,13 +770,14 @@ static int wl1271_plt_init(struct wl1271 *wl)
static
void
wl12xx_irq_ps_regulate_link
(
struct
wl1271
*
wl
,
u8
hlid
,
u8
tx_pkts
)
{
bool
fw_ps
;
bool
fw_ps
,
single_sta
;
/* only regulate station links */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
fw_ps
=
test_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
single_sta
=
(
wl
->
active_sta_count
==
1
);
/*
* Wake up from high level PS if the STA is asleep with too little
...
...
@@ -772,8 +786,12 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts)
if
(
!
fw_ps
||
tx_pkts
<
WL1271_PS_STA_MAX_PACKETS
)
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_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
/*
* Start high-level PS if the STA is asleep with enough blocks in FW.
* Make an exception if this is the only connected station. In this
* case FW-memory congestion is not a problem.
*/
else
if
(
!
single_sta
&&
fw_ps
&&
tx_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
...
...
@@ -1213,6 +1231,8 @@ static void wl1271_recovery_work(struct work_struct *work)
wl1271_info
(
"Hardware recovery in progress. FW ver: %s pc: 0x%x"
,
wl
->
chip
.
fw_ver_str
,
wl1271_read32
(
wl
,
SCR_PAD4
));
BUG_ON
(
bug_on_recovery
);
/*
* Advance security sequence number to overcome potential progress
* in the firmware during recovery. This doens't hurt if the network is
...
...
@@ -1222,9 +1242,6 @@ static void wl1271_recovery_work(struct work_struct *work)
test_bit
(
WL1271_FLAG_AP_STARTED
,
&
wl
->
flags
))
wl
->
tx_security_seq
+=
WL1271_TX_SQN_POST_RECOVERY_PADDING
;
if
(
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
ieee80211_connection_loss
(
wl
->
vif
);
/* Prevent spurious TX during FW restart */
ieee80211_stop_queues
(
wl
->
hw
);
...
...
@@ -1528,7 +1545,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
int
wl1271_tx_dummy_packet
(
struct
wl1271
*
wl
)
{
unsigned
long
flags
;
int
q
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
wl
->
dummy_packet
));
int
q
;
/* no need to queue a new dummy packet if one is already pending */
if
(
test_bit
(
WL1271_FLAG_DUMMY_PACKET_PENDING
,
&
wl
->
flags
))
return
0
;
q
=
wl1271_tx_get_queue
(
skb_get_queue_mapping
(
wl
->
dummy_packet
));
spin_lock_irqsave
(
&
wl
->
wl_lock
,
flags
);
set_bit
(
WL1271_FLAG_DUMMY_PACKET_PENDING
,
&
wl
->
flags
);
...
...
@@ -1802,9 +1825,15 @@ static u8 wl12xx_get_role_type(struct wl1271 *wl)
{
switch
(
wl
->
bss_type
)
{
case
BSS_TYPE_AP_BSS
:
if
(
wl
->
p2p
)
return
WL1271_ROLE_P2P_GO
;
else
return
WL1271_ROLE_AP
;
case
BSS_TYPE_STA_BSS
:
if
(
wl
->
p2p
)
return
WL1271_ROLE_P2P_CL
;
else
return
WL1271_ROLE_STA
;
case
BSS_TYPE_IBSS
:
...
...
@@ -1827,7 +1856,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
bool
booted
=
false
;
wl1271_debug
(
DEBUG_MAC80211
,
"mac80211 add interface type %d mac %pM"
,
vif
->
type
,
vif
->
addr
);
ieee80211_vif_type_p2p
(
vif
)
,
vif
->
addr
);
mutex_lock
(
&
wl
->
mutex
);
if
(
wl
->
vif
)
{
...
...
@@ -1847,7 +1876,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
goto
out
;
}
switch
(
vif
->
type
)
{
switch
(
ieee80211_vif_type_p2p
(
vif
))
{
case
NL80211_IFTYPE_P2P_CLIENT
:
wl
->
p2p
=
1
;
/* fall-through */
case
NL80211_IFTYPE_STATION
:
wl
->
bss_type
=
BSS_TYPE_STA_BSS
;
wl
->
set_bss_type
=
BSS_TYPE_STA_BSS
;
...
...
@@ -1856,6 +1888,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
wl
->
bss_type
=
BSS_TYPE_IBSS
;
wl
->
set_bss_type
=
BSS_TYPE_STA_BSS
;
break
;
case
NL80211_IFTYPE_P2P_GO
:
wl
->
p2p
=
1
;
/* fall-through */
case
NL80211_IFTYPE_AP
:
wl
->
bss_type
=
BSS_TYPE_AP_BSS
;
break
;
...
...
@@ -2051,6 +2086,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
wl
->
ssid_len
=
0
;
wl
->
bss_type
=
MAX_BSS_TYPE
;
wl
->
set_bss_type
=
MAX_BSS_TYPE
;
wl
->
p2p
=
0
;
wl
->
band
=
IEEE80211_BAND_2GHZ
;
wl
->
rx_counter
=
0
;
...
...
@@ -2075,6 +2111,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
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
));
wl
->
active_sta_count
=
0
;
/* The system link is always allocated */
__set_bit
(
WL12XX_SYSTEM_HLID
,
wl
->
links_map
);
...
...
@@ -3729,14 +3766,18 @@ static int wl1271_allocate_sta(struct wl1271 *wl,
wl_sta
->
hlid
=
WL1271_AP_STA_HLID_START
+
id
;
*
hlid
=
wl_sta
->
hlid
;
memcpy
(
wl
->
links
[
wl_sta
->
hlid
].
addr
,
sta
->
addr
,
ETH_ALEN
);
wl
->
active_sta_count
++
;
return
0
;
}
static
void
wl1271_free_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
void
wl1271_free_sta
(
struct
wl1271
*
wl
,
u8
hlid
)
{
int
id
=
hlid
-
WL1271_AP_STA_HLID_START
;
if
(
WARN_ON
(
!
test_bit
(
id
,
wl
->
ap_hlid_map
)))
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
if
(
!
test_bit
(
id
,
wl
->
ap_hlid_map
))
return
;
clear_bit
(
id
,
wl
->
ap_hlid_map
);
...
...
@@ -3745,6 +3786,7 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
wl1271_tx_reset_link_queues
(
wl
,
hlid
);
__clear_bit
(
hlid
,
&
wl
->
ap_ps_map
);
__clear_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
wl
->
active_sta_count
--
;
}
static
int
wl1271_op_sta_add
(
struct
ieee80211_hw
*
hw
,
...
...
@@ -4066,7 +4108,6 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
/* 11n STA capabilities */
#define HW_RX_HIGHEST_RATE 72
#ifdef CONFIG_WL12XX_HT
#define WL12XX_HT_CAP { \
.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
...
...
@@ -4079,11 +4120,6 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
.tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
}, \
}
#else
#define WL12XX_HT_CAP { \
.ht_supported = false, \
}
#endif
/* can't be const, mac80211 writes to this */
static
struct
ieee80211_supported_band
wl1271_band_2ghz
=
{
...
...
@@ -4483,15 +4519,19 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
IEEE80211_HW_SUPPORTS_CQM_RSSI
|
IEEE80211_HW_REPORTS_TX_ACK_STATUS
|
IEEE80211_HW_SPECTRUM_MGMT
|
IEEE80211_HW_AP_LINK_PS
;
IEEE80211_HW_AP_LINK_PS
|
IEEE80211_HW_AMPDU_AGGREGATION
|
IEEE80211_HW_TX_AMPDU_SETUP_IN_HW
;
wl
->
hw
->
wiphy
->
cipher_suites
=
cipher_suites
;
wl
->
hw
->
wiphy
->
n_cipher_suites
=
ARRAY_SIZE
(
cipher_suites
);
wl
->
hw
->
wiphy
->
interface_modes
=
BIT
(
NL80211_IFTYPE_STATION
)
|
BIT
(
NL80211_IFTYPE_ADHOC
)
|
BIT
(
NL80211_IFTYPE_AP
);
BIT
(
NL80211_IFTYPE_ADHOC
)
|
BIT
(
NL80211_IFTYPE_AP
)
|
BIT
(
NL80211_IFTYPE_P2P_CLIENT
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
);
wl
->
hw
->
wiphy
->
max_scan_ssids
=
1
;
wl
->
hw
->
wiphy
->
max_sched_scan_ssids
=
8
;
wl
->
hw
->
wiphy
->
max_sched_scan_ssids
=
16
;
wl
->
hw
->
wiphy
->
max_match_sets
=
16
;
/*
* Maximum length of elements in scanning probe request templates
* should be the maximum length possible for a template, without
...
...
@@ -4500,6 +4540,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
wl
->
hw
->
wiphy
->
max_scan_ie_len
=
WL1271_CMD_TEMPL_DFLT_SIZE
-
sizeof
(
struct
ieee80211_header
);
wl
->
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_AP_UAPSD
;
/* make sure all our channels fit in the scanned_ch bitmask */
BUILD_BUG_ON
(
ARRAY_SIZE
(
wl1271_channels
)
+
ARRAY_SIZE
(
wl1271_channels_5ghz
)
>
...
...
@@ -4625,6 +4667,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
wl
->
session_counter
=
0
;
wl
->
ap_bcast_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
ap_global_hlid
=
WL12XX_INVALID_LINK_ID
;
wl
->
active_sta_count
=
0
;
setup_timer
(
&
wl
->
rx_streaming_timer
,
wl1271_rx_streaming_timer
,
(
unsigned
long
)
wl
);
wl
->
fwlog_size
=
0
;
...
...
@@ -4776,6 +4819,9 @@ module_param_named(fwlog, fwlog_param, charp, 0);
MODULE_PARM_DESC
(
keymap
,
"FW logger options: continuous, ondemand, dbgpins or disable"
);
module_param
(
bug_on_recovery
,
bool
,
S_IRUSR
|
S_IWUSR
);
MODULE_PARM_DESC
(
bug_on_recovery
,
"BUG() on fw recovery"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Luciano Coelho <coelho@ti.com>"
);
MODULE_AUTHOR
(
"Juuso Oikarinen <juuso.oikarinen@nokia.com>"
);
drivers/net/wireless/wl12xx/ps.c
浏览文件 @
376cf5d3
...
...
@@ -199,15 +199,19 @@ static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid)
unsigned
long
flags
;
int
filtered
[
NUM_TX_QUEUES
];
/* filter all frames currently
the low level queu
s for this hlid */
/* filter all frames currently
in the low level queue
s for this hlid */
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
{
filtered
[
i
]
=
0
;
while
((
skb
=
skb_dequeue
(
&
wl
->
links
[
hlid
].
tx_queue
[
i
])))
{
filtered
[
i
]
++
;
if
(
WARN_ON
(
wl12xx_is_dummy_packet
(
wl
,
skb
)))
continue
;
info
=
IEEE80211_SKB_CB
(
skb
);
info
->
flags
|=
IEEE80211_TX_STAT_TX_FILTERED
;
info
->
status
.
rates
[
0
].
idx
=
-
1
;
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
filtered
[
i
]
++
;
}
}
...
...
drivers/net/wireless/wl12xx/rx.c
浏览文件 @
376cf5d3
...
...
@@ -66,11 +66,9 @@ static void wl1271_rx_status(struct wl1271 *wl,
status
->
rate_idx
=
wl1271_rate_to_idx
(
desc
->
rate
,
status
->
band
);
#ifdef CONFIG_WL12XX_HT
/* 11n support */
if
(
desc
->
rate
<=
CONF_HW_RXTX_RATE_MCS0
)
status
->
flag
|=
RX_FLAG_HT
;
#endif
status
->
signal
=
desc
->
rssi
;
...
...
@@ -107,6 +105,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
u8
beacon
=
0
;
u8
is_data
=
0
;
u8
reserved
=
unaligned
?
NET_IP_ALIGN
:
0
;
u16
seq_num
;
/*
* In PLT mode we seem to get frames and mac80211 warns about them,
...
...
@@ -169,9 +168,11 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
wl1271_rx_status
(
wl
,
desc
,
IEEE80211_SKB_RXCB
(
skb
),
beacon
);
wl1271_debug
(
DEBUG_RX
,
"rx skb 0x%p: %d B %s"
,
skb
,
seq_num
=
(
le16_to_cpu
(
hdr
->
seq_ctrl
)
&
IEEE80211_SCTL_SEQ
)
>>
4
;
wl1271_debug
(
DEBUG_RX
,
"rx skb 0x%p: %d B %s seq %d"
,
skb
,
skb
->
len
-
desc
->
pad_len
,
beacon
?
"beacon"
:
""
);
beacon
?
"beacon"
:
""
,
seq_num
);
skb_trim
(
skb
,
skb
->
len
-
desc
->
pad_len
);
...
...
drivers/net/wireless/wl12xx/scan.c
浏览文件 @
376cf5d3
...
...
@@ -65,8 +65,9 @@ void wl1271_scan_complete_work(struct work_struct *work)
/* 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
)))
{
if
(((
is_sta
&&
!
test_bit
(
WL1271_FLAG_STA_ASSOCIATED
,
&
wl
->
flags
))
||
(
is_ibss
&&
!
test_bit
(
WL1271_FLAG_IBSS_JOINED
,
&
wl
->
flags
)))
&&
!
test_bit
(
wl
->
dev_role_id
,
wl
->
roc_map
))
{
/* restore remain on channel */
wl12xx_cmd_role_start_dev
(
wl
);
wl12xx_roc
(
wl
,
wl
->
dev_role_id
);
...
...
@@ -164,9 +165,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band,
goto
out
;
}
/* We always use high priority scans */
scan_options
=
WL1271_SCAN_OPT_PRIORITY_HIGH
;
/* No SSIDs means that we have a forced passive scan */
if
(
passive
||
wl
->
scan
.
req
->
n_ssids
==
0
)
scan_options
|=
WL1271_SCAN_OPT_PASSIVE
;
...
...
@@ -473,35 +471,87 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl,
cfg
->
passive
[
2
]
||
cfg
->
active
[
2
];
}
/* Returns 0 if no wildcard is used, 1 if wildcard is used or a
* negative value on error */
/* Returns the scan type to be used or a negative value on error */
static
int
wl12xx_scan_sched_scan_ssid_list
(
struct
wl1271
*
wl
,
struct
cfg80211_sched_scan_request
*
req
)
{
struct
wl1271_cmd_sched_scan_ssid_list
*
cmd
=
NULL
;
struct
cfg80211_ssid
*
ssid
=
req
->
ssids
;
int
ret
,
wildcard
=
0
;
struct
cfg80211_match_set
*
sets
=
req
->
match_sets
;
struct
cfg80211_ssid
*
ssids
=
req
->
ssids
;
int
ret
=
0
,
type
,
i
,
j
,
n_match_ssids
=
0
;
wl1271_debug
(
DEBUG_CMD
,
"cmd sched scan ssid list"
);
/* count the match sets that contain SSIDs */
for
(
i
=
0
;
i
<
req
->
n_match_sets
;
i
++
)
if
(
sets
[
i
].
ssid
.
ssid_len
>
0
)
n_match_ssids
++
;
/* No filter, no ssids or only bcast ssid */
if
(
!
n_match_ssids
&&
(
!
req
->
n_ssids
||
(
req
->
n_ssids
==
1
&&
req
->
ssids
[
0
].
ssid_len
==
0
)))
{
type
=
SCAN_SSID_FILTER_ANY
;
goto
out
;
}
cmd
=
kzalloc
(
sizeof
(
*
cmd
),
GFP_KERNEL
);
if
(
!
cmd
)
return
-
ENOMEM
;
if
(
!
cmd
)
{
ret
=
-
ENOMEM
;
goto
out
;
}
while
((
cmd
->
n_ssids
<
req
->
n_ssids
)
&&
ssid
)
{
if
(
ssid
->
ssid_len
==
0
)
{
wildcard
=
1
;
cmd
->
ssids
[
cmd
->
n_ssids
].
type
=
SCAN_SSID_TYPE_PUBLIC
;
}
else
{
cmd
->
ssids
[
cmd
->
n_ssids
].
type
=
SCAN_SSID_TYPE_HIDDEN
;
if
(
!
n_match_ssids
)
{
/* No filter, with ssids */
type
=
SCAN_SSID_FILTER_DISABLED
;
for
(
i
=
0
;
i
<
req
->
n_ssids
;
i
++
)
{
cmd
->
ssids
[
cmd
->
n_ssids
].
type
=
(
ssids
[
i
].
ssid_len
)
?
SCAN_SSID_TYPE_HIDDEN
:
SCAN_SSID_TYPE_PUBLIC
;
cmd
->
ssids
[
cmd
->
n_ssids
].
len
=
ssids
[
i
].
ssid_len
;
memcpy
(
cmd
->
ssids
[
cmd
->
n_ssids
].
ssid
,
ssids
[
i
].
ssid
,
ssids
[
i
].
ssid_len
);
cmd
->
n_ssids
++
;
}
cmd
->
ssids
[
cmd
->
n_ssids
].
len
=
ssid
->
ssid_len
;
memcpy
(
cmd
->
ssids
[
cmd
->
n_ssids
].
ssid
,
ssid
->
ssid
,
ssid
->
ssid_len
);
ssid
++
;
}
else
{
type
=
SCAN_SSID_FILTER_LIST
;
/* Add all SSIDs from the filters */
for
(
i
=
0
;
i
<
req
->
n_match_sets
;
i
++
)
{
/* ignore sets without SSIDs */
if
(
!
sets
[
i
].
ssid
.
ssid_len
)
continue
;
cmd
->
ssids
[
cmd
->
n_ssids
].
type
=
SCAN_SSID_TYPE_PUBLIC
;
cmd
->
ssids
[
cmd
->
n_ssids
].
len
=
sets
[
i
].
ssid
.
ssid_len
;
memcpy
(
cmd
->
ssids
[
cmd
->
n_ssids
].
ssid
,
sets
[
i
].
ssid
.
ssid
,
sets
[
i
].
ssid
.
ssid_len
);
cmd
->
n_ssids
++
;
}
if
((
req
->
n_ssids
>
1
)
||
(
req
->
n_ssids
==
1
&&
req
->
ssids
[
0
].
ssid_len
>
0
))
{
/*
* Mark all the SSIDs passed in the SSID list as HIDDEN,
* so they're used in probe requests.
*/
for
(
i
=
0
;
i
<
req
->
n_ssids
;
i
++
)
{
for
(
j
=
0
;
j
<
cmd
->
n_ssids
;
j
++
)
if
(
!
memcmp
(
req
->
ssids
[
i
].
ssid
,
cmd
->
ssids
[
j
].
ssid
,
req
->
ssids
[
i
].
ssid_len
))
{
cmd
->
ssids
[
j
].
type
=
SCAN_SSID_TYPE_HIDDEN
;
break
;
}
/* Fail if SSID isn't present in the filters */
if
(
j
==
req
->
n_ssids
)
{
ret
=
-
EINVAL
;
goto
out_free
;
}
}
}
}
wl1271_dump
(
DEBUG_SCAN
,
"SSID_LIST: "
,
cmd
,
sizeof
(
*
cmd
));
...
...
@@ -509,13 +559,15 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
sizeof
(
*
cmd
),
0
);
if
(
ret
<
0
)
{
wl1271_error
(
"cmd sched scan ssid list failed"
);
goto
out
;
goto
out
_free
;
}
ret
=
wildcard
;
out:
out_free:
kfree
(
cmd
);
out:
if
(
ret
<
0
)
return
ret
;
return
type
;
}
int
wl1271_scan_sched_scan_config
(
struct
wl1271
*
wl
,
...
...
@@ -550,21 +602,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
cfg
->
intervals
[
i
]
=
cpu_to_le32
(
req
->
interval
);
cfg
->
ssid_len
=
0
;
if
(
req
->
n_ssids
==
0
)
{
wl1271_debug
(
DEBUG_SCAN
,
"using SCAN_SSID_FILTER_ANY"
);
cfg
->
filter_type
=
SCAN_SSID_FILTER_ANY
;
}
else
{
ret
=
wl12xx_scan_sched_scan_ssid_list
(
wl
,
req
);
if
(
ret
<
0
)
goto
out
;
if
(
ret
)
{
wl1271_debug
(
DEBUG_SCAN
,
"using SCAN_SSID_FILTER_DISABLED"
);
cfg
->
filter_type
=
SCAN_SSID_FILTER_DISABLED
;
}
else
{
wl1271_debug
(
DEBUG_SCAN
,
"using SCAN_SSID_FILTER_LIST"
);
cfg
->
filter_type
=
SCAN_SSID_FILTER_LIST
;
}
}
cfg
->
filter_type
=
ret
;
wl1271_debug
(
DEBUG_SCAN
,
"filter_type = %d"
,
cfg
->
filter_type
);
if
(
!
wl1271_scan_sched_scan_channels
(
wl
,
req
,
cfg
))
{
wl1271_error
(
"scan channel list is empty"
);
...
...
drivers/net/wireless/wl12xx/tx.c
浏览文件 @
376cf5d3
...
...
@@ -30,6 +30,7 @@
#include "reg.h"
#include "ps.h"
#include "tx.h"
#include "event.h"
static
int
wl1271_set_default_wep_key
(
struct
wl1271
*
wl
,
u8
id
)
{
...
...
@@ -125,25 +126,31 @@ 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
;
bool
fw_ps
,
single_sta
;
u8
tx_pkts
;
/* only regulate station links */
if
(
hlid
<
WL1271_AP_STA_HLID_START
)
return
;
if
(
WARN_ON
(
!
wl1271_is_active_sta
(
wl
,
hlid
)))
return
;
fw_ps
=
test_bit
(
hlid
,
(
unsigned
long
*
)
&
wl
->
ap_fw_ps_map
);
tx_pkts
=
wl
->
links
[
hlid
].
allocated_pkts
;
single_sta
=
(
wl
->
active_sta_count
==
1
);
/*
* 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.
* Make an exception if this is the only connected station. In this
* case FW-memory congestion is not a problem.
*/
if
(
fw_ps
&&
tx_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
if
(
!
single_sta
&&
fw_ps
&&
tx_pkts
>=
WL1271_PS_STA_MAX_PACKETS
)
wl1271_ps_link_start
(
wl
,
hlid
,
true
);
}
static
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
)
{
return
wl
->
dummy_packet
==
skb
;
}
...
...
@@ -453,7 +460,6 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
rate_set
>>=
1
;
}
#ifdef CONFIG_WL12XX_HT
/* MCS rates indication are on bits 16 - 23 */
rate_set
>>=
HW_HT_RATES_OFFSET
-
band
->
n_bitrates
;
...
...
@@ -462,7 +468,6 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
enabled_rates
|=
(
CONF_HW_BIT_RATE_MCS_0
<<
bit
);
rate_set
>>=
1
;
}
#endif
return
enabled_rates
;
}
...
...
@@ -886,6 +891,7 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
/* TX failure */
if
(
wl
->
bss_type
==
BSS_TYPE_AP_BSS
)
{
for
(
i
=
0
;
i
<
AP_MAX_LINKS
;
i
++
)
{
wl1271_free_sta
(
wl
,
i
);
wl1271_tx_reset_link_queues
(
wl
,
i
);
wl
->
links
[
i
].
allocated_pkts
=
0
;
wl
->
links
[
i
].
prev_freed_pkts
=
0
;
...
...
@@ -905,10 +911,14 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
ieee80211_tx_status_ni
(
wl
->
hw
,
skb
);
}
}
wl
->
tx_queue_count
[
i
]
=
0
;
}
wl
->
ba_rx_bitmap
=
0
;
}
for
(
i
=
0
;
i
<
NUM_TX_QUEUES
;
i
++
)
wl
->
tx_queue_count
[
i
]
=
0
;
wl
->
stopped_queues_map
=
0
;
/*
...
...
drivers/net/wireless/wl12xx/tx.h
浏览文件 @
376cf5d3
...
...
@@ -214,5 +214,9 @@ u32 wl1271_tx_min_rate_get(struct wl1271 *wl);
u8
wl12xx_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
);
bool
wl12xx_is_dummy_packet
(
struct
wl1271
*
wl
,
struct
sk_buff
*
skb
);
/* from main.c */
void
wl1271_free_sta
(
struct
wl1271
*
wl
,
u8
hlid
);
#endif
drivers/net/wireless/wl12xx/wl12xx.h
浏览文件 @
376cf5d3
...
...
@@ -234,14 +234,14 @@ struct wl1271_stats {
#define NUM_TX_QUEUES 4
#define NUM_RX_PKT_DESC 8
#define AP_MAX_STATIONS
5
#define AP_MAX_STATIONS
8
/* 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
)
#define AP_MAX_LINKS (AP_MAX_STATIONS +
WL1271_AP_STA_HLID_START
)
/* FW status registers */
struct
wl12xx_fw_status
{
...
...
@@ -402,6 +402,7 @@ struct wl1271 {
u8
mac_addr
[
ETH_ALEN
];
u8
bss_type
;
u8
set_bss_type
;
u8
p2p
;
/* we are using p2p role */
u8
ssid
[
IEEE80211_MAX_SSID_LEN
+
1
];
u8
ssid_len
;
int
channel
;
...
...
@@ -626,6 +627,9 @@ struct wl1271 {
/* number of currently active RX BA sessions */
int
ba_rx_session_count
;
/* AP-mode - number of currently connected stations */
int
active_sta_count
;
};
struct
wl1271_station
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录