Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
59e25676
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
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看板
提交
59e25676
编写于
8月 28, 2014
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://github.com/kvalo/ath
上级
7bb75da1
0fdc14e4
变更
30
展开全部
隐藏空白更改
内联
并排
Showing
30 changed file
with
4132 addition
and
2203 deletion
+4132
-2203
drivers/net/wireless/ath/ath10k/Kconfig
drivers/net/wireless/ath/ath10k/Kconfig
+1
-0
drivers/net/wireless/ath/ath10k/Makefile
drivers/net/wireless/ath/ath10k/Makefile
+1
-0
drivers/net/wireless/ath/ath10k/bmi.c
drivers/net/wireless/ath/ath10k/bmi.c
+26
-26
drivers/net/wireless/ath/ath10k/ce.c
drivers/net/wireless/ath/ath10k/ce.c
+66
-119
drivers/net/wireless/ath/ath10k/ce.h
drivers/net/wireless/ath/ath10k/ce.h
+7
-21
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.c
+128
-118
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/core.h
+59
-7
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/debug.c
+291
-48
drivers/net/wireless/ath/ath10k/debug.h
drivers/net/wireless/ath/ath10k/debug.h
+27
-7
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/htc.c
+55
-60
drivers/net/wireless/ath/ath10k/htc.h
drivers/net/wireless/ath/ath10k/htc.h
+2
-5
drivers/net/wireless/ath/ath10k/htt.c
drivers/net/wireless/ath/ath10k/htt.c
+6
-3
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/htt_rx.c
+112
-59
drivers/net/wireless/ath/ath10k/htt_tx.c
drivers/net/wireless/ath/ath10k/htt_tx.c
+30
-16
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/hw.h
+4
-1
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/mac.c
+398
-319
drivers/net/wireless/ath/ath10k/mac.h
drivers/net/wireless/ath/ath10k/mac.h
+4
-2
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.c
+679
-858
drivers/net/wireless/ath/ath10k/pci.h
drivers/net/wireless/ath/ath10k/pci.h
+24
-80
drivers/net/wireless/ath/ath10k/spectral.c
drivers/net/wireless/ath/ath10k/spectral.c
+561
-0
drivers/net/wireless/ath/ath10k/spectral.h
drivers/net/wireless/ath/ath10k/spectral.h
+90
-0
drivers/net/wireless/ath/ath10k/txrx.c
drivers/net/wireless/ath/ath10k/txrx.c
+9
-8
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.c
+842
-247
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/ath/ath10k/wmi.h
+591
-108
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath6kl/init.c
+1
-1
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/main.c
+1
-1
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath6kl/sdio.c
+1
-0
drivers/net/wireless/ath/ath6kl/usb.c
drivers/net/wireless/ath/ath6kl/usb.c
+1
-20
drivers/net/wireless/ath/ath9k/spectral.h
drivers/net/wireless/ath/ath9k/spectral.h
+2
-69
drivers/net/wireless/ath/spectral_common.h
drivers/net/wireless/ath/spectral_common.h
+113
-0
未找到文件。
drivers/net/wireless/ath/ath10k/Kconfig
浏览文件 @
59e25676
...
...
@@ -25,6 +25,7 @@ config ATH10K_DEBUG
config ATH10K_DEBUGFS
bool "Atheros ath10k debugfs support"
depends on ATH10K
select RELAY
---help---
Enabled debugfs support
...
...
drivers/net/wireless/ath/ath10k/Makefile
浏览文件 @
59e25676
...
...
@@ -10,6 +10,7 @@ ath10k_core-y += mac.o \
wmi.o
\
bmi.o
ath10k_core-$(CONFIG_ATH10K_DEBUGFS)
+=
spectral.o
ath10k_core-$(CONFIG_ATH10K_TRACING)
+=
trace.o
obj-$(CONFIG_ATH10K_PCI)
+=
ath10k_pci.o
...
...
drivers/net/wireless/ath/ath10k/bmi.c
浏览文件 @
59e25676
...
...
@@ -22,7 +22,7 @@
void
ath10k_bmi_start
(
struct
ath10k
*
ar
)
{
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi start
\n
"
);
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi start
\n
"
);
ar
->
bmi
.
done_sent
=
false
;
}
...
...
@@ -33,10 +33,10 @@ int ath10k_bmi_done(struct ath10k *ar)
u32
cmdlen
=
sizeof
(
cmd
.
id
)
+
sizeof
(
cmd
.
done
);
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi done
\n
"
);
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi done
\n
"
);
if
(
ar
->
bmi
.
done_sent
)
{
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi skipped
\n
"
);
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi skipped
\n
"
);
return
0
;
}
...
...
@@ -45,7 +45,7 @@ int ath10k_bmi_done(struct ath10k *ar)
ret
=
ath10k_hif_exchange_bmi_msg
(
ar
,
&
cmd
,
cmdlen
,
NULL
,
NULL
);
if
(
ret
)
{
ath10k_warn
(
"unable to write to the device: %d
\n
"
,
ret
);
ath10k_warn
(
ar
,
"unable to write to the device: %d
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -61,10 +61,10 @@ int ath10k_bmi_get_target_info(struct ath10k *ar,
u32
resplen
=
sizeof
(
resp
.
get_target_info
);
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi get target info
\n
"
);
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi get target info
\n
"
);
if
(
ar
->
bmi
.
done_sent
)
{
ath10k_warn
(
"BMI Get Target Info Command disallowed
\n
"
);
ath10k_warn
(
ar
,
"BMI Get Target Info Command disallowed
\n
"
);
return
-
EBUSY
;
}
...
...
@@ -72,12 +72,12 @@ int ath10k_bmi_get_target_info(struct ath10k *ar,
ret
=
ath10k_hif_exchange_bmi_msg
(
ar
,
&
cmd
,
cmdlen
,
&
resp
,
&
resplen
);
if
(
ret
)
{
ath10k_warn
(
"unable to get target info from device
\n
"
);
ath10k_warn
(
ar
,
"unable to get target info from device
\n
"
);
return
ret
;
}
if
(
resplen
<
sizeof
(
resp
.
get_target_info
))
{
ath10k_warn
(
"invalid get_target_info response length (%d)
\n
"
,
ath10k_warn
(
ar
,
"invalid get_target_info response length (%d)
\n
"
,
resplen
);
return
-
EIO
;
}
...
...
@@ -97,11 +97,11 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
u32
rxlen
;
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi read address 0x%x length %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi read address 0x%x length %d
\n
"
,
address
,
length
);
if
(
ar
->
bmi
.
done_sent
)
{
ath10k_warn
(
"command disallowed
\n
"
);
ath10k_warn
(
ar
,
"command disallowed
\n
"
);
return
-
EBUSY
;
}
...
...
@@ -115,7 +115,7 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
ret
=
ath10k_hif_exchange_bmi_msg
(
ar
,
&
cmd
,
cmdlen
,
&
resp
,
&
rxlen
);
if
(
ret
)
{
ath10k_warn
(
"unable to read from the device (%d)
\n
"
,
ath10k_warn
(
ar
,
"unable to read from the device (%d)
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -137,11 +137,11 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
u32
txlen
;
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi write address 0x%x length %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi write address 0x%x length %d
\n
"
,
address
,
length
);
if
(
ar
->
bmi
.
done_sent
)
{
ath10k_warn
(
"command disallowed
\n
"
);
ath10k_warn
(
ar
,
"command disallowed
\n
"
);
return
-
EBUSY
;
}
...
...
@@ -159,7 +159,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
ret
=
ath10k_hif_exchange_bmi_msg
(
ar
,
&
cmd
,
hdrlen
+
txlen
,
NULL
,
NULL
);
if
(
ret
)
{
ath10k_warn
(
"unable to write to the device (%d)
\n
"
,
ath10k_warn
(
ar
,
"unable to write to the device (%d)
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -183,11 +183,11 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
u32
resplen
=
sizeof
(
resp
.
execute
);
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi execute address 0x%x param 0x%x
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi execute address 0x%x param 0x%x
\n
"
,
address
,
param
);
if
(
ar
->
bmi
.
done_sent
)
{
ath10k_warn
(
"command disallowed
\n
"
);
ath10k_warn
(
ar
,
"command disallowed
\n
"
);
return
-
EBUSY
;
}
...
...
@@ -197,19 +197,19 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
ret
=
ath10k_hif_exchange_bmi_msg
(
ar
,
&
cmd
,
cmdlen
,
&
resp
,
&
resplen
);
if
(
ret
)
{
ath10k_warn
(
"unable to read from the device
\n
"
);
ath10k_warn
(
ar
,
"unable to read from the device
\n
"
);
return
ret
;
}
if
(
resplen
<
sizeof
(
resp
.
execute
))
{
ath10k_warn
(
"invalid execute response length (%d)
\n
"
,
ath10k_warn
(
ar
,
"invalid execute response length (%d)
\n
"
,
resplen
);
return
-
EIO
;
}
*
result
=
__le32_to_cpu
(
resp
.
execute
.
result
);
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi execute result 0x%x
\n
"
,
*
result
);
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi execute result 0x%x
\n
"
,
*
result
);
return
0
;
}
...
...
@@ -221,11 +221,11 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
u32
txlen
;
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi lz data buffer 0x%p length %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi lz data buffer 0x%p length %d
\n
"
,
buffer
,
length
);
if
(
ar
->
bmi
.
done_sent
)
{
ath10k_warn
(
"command disallowed
\n
"
);
ath10k_warn
(
ar
,
"command disallowed
\n
"
);
return
-
EBUSY
;
}
...
...
@@ -241,7 +241,7 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
ret
=
ath10k_hif_exchange_bmi_msg
(
ar
,
&
cmd
,
hdrlen
+
txlen
,
NULL
,
NULL
);
if
(
ret
)
{
ath10k_warn
(
"unable to write to the device
\n
"
);
ath10k_warn
(
ar
,
"unable to write to the device
\n
"
);
return
ret
;
}
...
...
@@ -258,11 +258,11 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address)
u32
cmdlen
=
sizeof
(
cmd
.
id
)
+
sizeof
(
cmd
.
lz_start
);
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
"bmi lz stream start address 0x%x
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi lz stream start address 0x%x
\n
"
,
address
);
if
(
ar
->
bmi
.
done_sent
)
{
ath10k_warn
(
"command disallowed
\n
"
);
ath10k_warn
(
ar
,
"command disallowed
\n
"
);
return
-
EBUSY
;
}
...
...
@@ -271,7 +271,7 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address)
ret
=
ath10k_hif_exchange_bmi_msg
(
ar
,
&
cmd
,
cmdlen
,
NULL
,
NULL
);
if
(
ret
)
{
ath10k_warn
(
"unable to Start LZ Stream to the device
\n
"
);
ath10k_warn
(
ar
,
"unable to Start LZ Stream to the device
\n
"
);
return
ret
;
}
...
...
@@ -286,7 +286,7 @@ int ath10k_bmi_fast_download(struct ath10k *ar,
u32
trailer_len
=
length
-
head_len
;
int
ret
;
ath10k_dbg
(
ATH10K_DBG_BMI
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BMI
,
"bmi fast download address 0x%x buffer 0x%p length %d
\n
"
,
address
,
buffer
,
length
);
...
...
drivers/net/wireless/ath/ath10k/ce.c
浏览文件 @
59e25676
...
...
@@ -284,13 +284,9 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
int
ret
=
0
;
if
(
nbytes
>
ce_state
->
src_sz_max
)
ath10k_warn
(
"%s: send more we can (nbytes: %d, max: %d)
\n
"
,
ath10k_warn
(
ar
,
"%s: send more we can (nbytes: %d, max: %d)
\n
"
,
__func__
,
nbytes
,
ce_state
->
src_sz_max
);
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
ret
;
if
(
unlikely
(
CE_RING_DELTA
(
nentries_mask
,
write_index
,
sw_index
-
1
)
<=
0
))
{
ret
=
-
ENOSR
;
...
...
@@ -325,7 +321,6 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
src_ring
->
write_index
=
write_index
;
exit:
ath10k_pci_sleep
(
ar
);
return
ret
;
}
...
...
@@ -390,49 +385,57 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe)
return
delta
;
}
int
ath10k_ce_recv_buf_enqueue
(
struct
ath10k_ce_pipe
*
ce_state
,
void
*
per_recv_context
,
u32
buffer
)
int
__ath10k_ce_rx_num_free_bufs
(
struct
ath10k_ce_pipe
*
pipe
)
{
struct
ath10k_ce_ring
*
dest_ring
=
ce_state
->
dest_ring
;
u32
ctrl_addr
=
ce_state
->
ctrl_addr
;
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k
*
ar
=
pipe
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ath10k_ce_ring
*
dest_ring
=
pipe
->
dest_ring
;
unsigned
int
nentries_mask
=
dest_ring
->
nentries_mask
;
unsigned
int
write_index
;
unsigned
int
sw_index
;
int
ret
;
unsigned
int
write_index
=
dest_ring
->
write_index
;
unsigned
int
sw_index
=
dest_ring
->
sw_index
;
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
write_index
=
dest_ring
->
write_index
;
sw_index
=
dest_ring
->
sw_index
;
lockdep_assert_held
(
&
ar_pci
->
ce_lock
);
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
goto
out
;
return
CE_RING_DELTA
(
nentries_mask
,
write_index
,
sw_index
-
1
);
}
if
(
CE_RING_DELTA
(
nentries_mask
,
write_index
,
sw_index
-
1
)
>
0
)
{
struct
ce_desc
*
base
=
dest_ring
->
base_addr_owner_space
;
struct
ce_desc
*
desc
=
CE_DEST_RING_TO_DESC
(
base
,
write_index
);
int
__ath10k_ce_rx_post_buf
(
struct
ath10k_ce_pipe
*
pipe
,
void
*
ctx
,
u32
paddr
)
{
struct
ath10k
*
ar
=
pipe
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ath10k_ce_ring
*
dest_ring
=
pipe
->
dest_ring
;
unsigned
int
nentries_mask
=
dest_ring
->
nentries_mask
;
unsigned
int
write_index
=
dest_ring
->
write_index
;
unsigned
int
sw_index
=
dest_ring
->
sw_index
;
struct
ce_desc
*
base
=
dest_ring
->
base_addr_owner_space
;
struct
ce_desc
*
desc
=
CE_DEST_RING_TO_DESC
(
base
,
write_index
);
u32
ctrl_addr
=
pipe
->
ctrl_addr
;
/* Update destination descriptor */
desc
->
addr
=
__cpu_to_le32
(
buffer
);
desc
->
nbytes
=
0
;
lockdep_assert_held
(
&
ar_pci
->
ce_lock
);
dest_ring
->
per_transfer_context
[
write_index
]
=
per_recv_context
;
if
(
CE_RING_DELTA
(
nentries_mask
,
write_index
,
sw_index
-
1
)
==
0
)
return
-
EIO
;
/* Update Destination Ring Write Index */
write_index
=
CE_RING_IDX_INCR
(
nentries_mask
,
write_index
);
ath10k_ce_dest_ring_write_index_set
(
ar
,
ctrl_addr
,
write_index
);
dest_ring
->
write_index
=
write_index
;
ret
=
0
;
}
else
{
ret
=
-
EIO
;
}
ath10k_pci_sleep
(
ar
);
desc
->
addr
=
__cpu_to_le32
(
paddr
);
desc
->
nbytes
=
0
;
dest_ring
->
per_transfer_context
[
write_index
]
=
ctx
;
write_index
=
CE_RING_IDX_INCR
(
nentries_mask
,
write_index
);
ath10k_ce_dest_ring_write_index_set
(
ar
,
ctrl_addr
,
write_index
);
dest_ring
->
write_index
=
write_index
;
return
0
;
}
int
ath10k_ce_rx_post_buf
(
struct
ath10k_ce_pipe
*
pipe
,
void
*
ctx
,
u32
paddr
)
{
struct
ath10k
*
ar
=
pipe
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
int
ret
;
out:
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
ret
=
__ath10k_ce_rx_post_buf
(
pipe
,
ctx
,
paddr
);
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
return
ret
;
...
...
@@ -588,7 +591,6 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
unsigned
int
sw_index
=
src_ring
->
sw_index
;
struct
ce_desc
*
sdesc
,
*
sbase
;
unsigned
int
read_index
;
int
ret
;
if
(
src_ring
->
hw_index
==
sw_index
)
{
/*
...
...
@@ -599,18 +601,12 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
* value of the HW index has become stale.
*/
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
ret
;
read_index
=
ath10k_ce_src_ring_read_index_get
(
ar
,
ctrl_addr
);
if
(
read_index
==
0xffffffff
)
return
-
ENODEV
;
read_index
&=
nentries_mask
;
src_ring
->
hw_index
=
read_index
;
ath10k_pci_sleep
(
ar
);
}
read_index
=
src_ring
->
hw_index
;
...
...
@@ -731,11 +727,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ath10k_ce_pipe
*
ce_state
=
&
ar_pci
->
ce_states
[
ce_id
];
u32
ctrl_addr
=
ce_state
->
ctrl_addr
;
int
ret
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
...
...
@@ -760,7 +751,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
ath10k_ce_engine_int_status_clear
(
ar
,
ctrl_addr
,
CE_WATERMARK_MASK
);
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
ath10k_pci_sleep
(
ar
);
}
/*
...
...
@@ -771,13 +761,9 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
void
ath10k_ce_per_engine_service_any
(
struct
ath10k
*
ar
)
{
int
ce_id
,
ret
;
int
ce_id
;
u32
intr_summary
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
intr_summary
=
CE_INTERRUPT_SUMMARY
(
ar
);
for
(
ce_id
=
0
;
intr_summary
&&
(
ce_id
<
CE_COUNT
);
ce_id
++
)
{
...
...
@@ -789,8 +775,6 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
ath10k_ce_per_engine_service
(
ar
,
ce_id
);
}
ath10k_pci_sleep
(
ar
);
}
/*
...
...
@@ -800,16 +784,11 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
*
* Called with ce_lock held.
*/
static
void
ath10k_ce_per_engine_handler_adjust
(
struct
ath10k_ce_pipe
*
ce_state
,
int
disable_copy_compl_intr
)
static
void
ath10k_ce_per_engine_handler_adjust
(
struct
ath10k_ce_pipe
*
ce_state
)
{
u32
ctrl_addr
=
ce_state
->
ctrl_addr
;
struct
ath10k
*
ar
=
ce_state
->
ar
;
int
ret
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
bool
disable_copy_compl_intr
=
ce_state
->
attr_flags
&
CE_ATTR_DIS_INTR
;
if
((
!
disable_copy_compl_intr
)
&&
(
ce_state
->
send_cb
||
ce_state
->
recv_cb
))
...
...
@@ -818,17 +797,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
ath10k_ce_copy_complete_intr_disable
(
ar
,
ctrl_addr
);
ath10k_ce_watermark_intr_disable
(
ar
,
ctrl_addr
);
ath10k_pci_sleep
(
ar
);
}
int
ath10k_ce_disable_interrupts
(
struct
ath10k
*
ar
)
{
int
ce_id
,
ret
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
ret
;
int
ce_id
;
for
(
ce_id
=
0
;
ce_id
<
CE_COUNT
;
ce_id
++
)
{
u32
ctrl_addr
=
ath10k_ce_base_address
(
ce_id
);
...
...
@@ -838,34 +811,16 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar)
ath10k_ce_watermark_intr_disable
(
ar
,
ctrl_addr
);
}
ath10k_pci_sleep
(
ar
);
return
0
;
}
void
ath10k_ce_send_cb_register
(
struct
ath10k_ce_pipe
*
ce_state
,
void
(
*
send_cb
)(
struct
ath10k_ce_pipe
*
),
int
disable_interrupts
)
void
ath10k_ce_enable_interrupts
(
struct
ath10k
*
ar
)
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
int
ce_id
;
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
ce_state
->
send_cb
=
send_cb
;
ath10k_ce_per_engine_handler_adjust
(
ce_state
,
disable_interrupts
);
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
}
void
ath10k_ce_recv_cb_register
(
struct
ath10k_ce_pipe
*
ce_state
,
void
(
*
recv_cb
)(
struct
ath10k_ce_pipe
*
))
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
ce_state
->
recv_cb
=
recv_cb
;
ath10k_ce_per_engine_handler_adjust
(
ce_state
,
0
);
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
for
(
ce_id
=
0
;
ce_id
<
CE_COUNT
;
ce_id
++
)
ath10k_ce_per_engine_handler_adjust
(
&
ar_pci
->
ce_states
[
ce_id
]);
}
static
int
ath10k_ce_init_src_ring
(
struct
ath10k
*
ar
,
...
...
@@ -898,7 +853,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
ath10k_ce_src_ring_lowmark_set
(
ar
,
ctrl_addr
,
0
);
ath10k_ce_src_ring_highmark_set
(
ar
,
ctrl_addr
,
nentries
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"boot init ce src ring id %d entries %d base_addr %p
\n
"
,
ce_id
,
nentries
,
src_ring
->
base_addr_owner_space
);
...
...
@@ -932,7 +887,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
ath10k_ce_dest_ring_lowmark_set
(
ar
,
ctrl_addr
,
0
);
ath10k_ce_dest_ring_highmark_set
(
ar
,
ctrl_addr
,
nentries
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"boot ce dest ring id %d entries %d base_addr %p
\n
"
,
ce_id
,
nentries
,
dest_ring
->
base_addr_owner_space
);
...
...
@@ -1067,7 +1022,9 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
* initialized by software/firmware.
*/
int
ath10k_ce_init_pipe
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
const
struct
ce_attr
*
attr
)
const
struct
ce_attr
*
attr
,
void
(
*
send_cb
)(
struct
ath10k_ce_pipe
*
),
void
(
*
recv_cb
)(
struct
ath10k_ce_pipe
*
))
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ath10k_ce_pipe
*
ce_state
=
&
ar_pci
->
ce_states
[
ce_id
];
...
...
@@ -1084,39 +1041,37 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
BUILD_BUG_ON
(
2
*
TARGET_10X_NUM_MSDU_DESC
>
(
CE_HTT_H2T_MSG_SRC_NENTRIES
-
1
));
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
ret
;
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
ce_state
->
ar
=
ar
;
ce_state
->
id
=
ce_id
;
ce_state
->
ctrl_addr
=
ath10k_ce_base_address
(
ce_id
);
ce_state
->
attr_flags
=
attr
->
flags
;
ce_state
->
src_sz_max
=
attr
->
src_sz_max
;
if
(
attr
->
src_nentries
)
ce_state
->
send_cb
=
send_cb
;
if
(
attr
->
dest_nentries
)
ce_state
->
recv_cb
=
recv_cb
;
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
if
(
attr
->
src_nentries
)
{
ret
=
ath10k_ce_init_src_ring
(
ar
,
ce_id
,
attr
);
if
(
ret
)
{
ath10k_err
(
"Failed to initialize CE src ring for ID: %d (%d)
\n
"
,
ath10k_err
(
ar
,
"Failed to initialize CE src ring for ID: %d (%d)
\n
"
,
ce_id
,
ret
);
goto
ou
t
;
return
re
t
;
}
}
if
(
attr
->
dest_nentries
)
{
ret
=
ath10k_ce_init_dest_ring
(
ar
,
ce_id
,
attr
);
if
(
ret
)
{
ath10k_err
(
"Failed to initialize CE dest ring for ID: %d (%d)
\n
"
,
ath10k_err
(
ar
,
"Failed to initialize CE dest ring for ID: %d (%d)
\n
"
,
ce_id
,
ret
);
goto
ou
t
;
return
re
t
;
}
}
out:
ath10k_pci_sleep
(
ar
);
return
ret
;
return
0
;
}
static
void
ath10k_ce_deinit_src_ring
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
)
...
...
@@ -1140,16 +1095,8 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
void
ath10k_ce_deinit_pipe
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
)
{
int
ret
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
ath10k_ce_deinit_src_ring
(
ar
,
ce_id
);
ath10k_ce_deinit_dest_ring
(
ar
,
ce_id
);
ath10k_pci_sleep
(
ar
);
}
int
ath10k_ce_alloc_pipe
(
struct
ath10k
*
ar
,
int
ce_id
,
...
...
@@ -1163,7 +1110,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
ce_state
->
src_ring
=
ath10k_ce_alloc_src_ring
(
ar
,
ce_id
,
attr
);
if
(
IS_ERR
(
ce_state
->
src_ring
))
{
ret
=
PTR_ERR
(
ce_state
->
src_ring
);
ath10k_err
(
"failed to allocate copy engine source ring %d: %d
\n
"
,
ath10k_err
(
ar
,
"failed to allocate copy engine source ring %d: %d
\n
"
,
ce_id
,
ret
);
ce_state
->
src_ring
=
NULL
;
return
ret
;
...
...
@@ -1175,7 +1122,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
attr
);
if
(
IS_ERR
(
ce_state
->
dest_ring
))
{
ret
=
PTR_ERR
(
ce_state
->
dest_ring
);
ath10k_err
(
"failed to allocate copy engine destination ring %d: %d
\n
"
,
ath10k_err
(
ar
,
"failed to allocate copy engine destination ring %d: %d
\n
"
,
ce_id
,
ret
);
ce_state
->
dest_ring
=
NULL
;
return
ret
;
...
...
drivers/net/wireless/ath/ath10k/ce.h
浏览文件 @
59e25676
...
...
@@ -162,30 +162,13 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
void
__ath10k_ce_send_revert
(
struct
ath10k_ce_pipe
*
pipe
);
void
ath10k_ce_send_cb_register
(
struct
ath10k_ce_pipe
*
ce_state
,
void
(
*
send_cb
)(
struct
ath10k_ce_pipe
*
),
int
disable_interrupts
);
int
ath10k_ce_num_free_src_entries
(
struct
ath10k_ce_pipe
*
pipe
);
/*==================Recv=======================*/
/*
* Make a buffer available to receive. The buffer must be at least of a
* minimal size appropriate for this copy engine (src_sz_max attribute).
* ce - which copy engine to use
* per_transfer_recv_context - context passed back to caller's recv_cb
* buffer - address of buffer in CE space
* Returns 0 on success; otherwise an error status.
*
* Implemenation note: Pushes a buffer to Dest ring.
*/
int
ath10k_ce_recv_buf_enqueue
(
struct
ath10k_ce_pipe
*
ce_state
,
void
*
per_transfer_recv_context
,
u32
buffer
);
void
ath10k_ce_recv_cb_register
(
struct
ath10k_ce_pipe
*
ce_state
,
void
(
*
recv_cb
)(
struct
ath10k_ce_pipe
*
));
int
__ath10k_ce_rx_num_free_bufs
(
struct
ath10k_ce_pipe
*
pipe
);
int
__ath10k_ce_rx_post_buf
(
struct
ath10k_ce_pipe
*
pipe
,
void
*
ctx
,
u32
paddr
);
int
ath10k_ce_rx_post_buf
(
struct
ath10k_ce_pipe
*
pipe
,
void
*
ctx
,
u32
paddr
);
/* recv flags */
/* Data is byte-swapped */
...
...
@@ -214,7 +197,9 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
/*==================CE Engine Initialization=======================*/
int
ath10k_ce_init_pipe
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
const
struct
ce_attr
*
attr
);
const
struct
ce_attr
*
attr
,
void
(
*
send_cb
)(
struct
ath10k_ce_pipe
*
),
void
(
*
recv_cb
)(
struct
ath10k_ce_pipe
*
));
void
ath10k_ce_deinit_pipe
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
);
int
ath10k_ce_alloc_pipe
(
struct
ath10k
*
ar
,
int
ce_id
,
const
struct
ce_attr
*
attr
);
...
...
@@ -245,6 +230,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
void
ath10k_ce_per_engine_service_any
(
struct
ath10k
*
ar
);
void
ath10k_ce_per_engine_service
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
);
int
ath10k_ce_disable_interrupts
(
struct
ath10k
*
ar
);
void
ath10k_ce_enable_interrupts
(
struct
ath10k
*
ar
);
/* ce_attr.flags values */
/* Use NonSnooping PCIe accesses? */
...
...
drivers/net/wireless/ath/ath10k/core.c
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath10k/core.h
浏览文件 @
59e25676
...
...
@@ -22,6 +22,8 @@
#include <linux/if_ether.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/uuid.h>
#include <linux/time.h>
#include "htt.h"
#include "htc.h"
...
...
@@ -31,6 +33,7 @@
#include "../ath.h"
#include "../regd.h"
#include "../dfs_pattern_detector.h"
#include "spectral.h"
#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
...
...
@@ -237,6 +240,7 @@ struct ath10k_vif {
bool
is_started
;
bool
is_up
;
bool
spectral_enabled
;
u32
aid
;
u8
bssid
[
ETH_ALEN
];
...
...
@@ -276,11 +280,20 @@ struct ath10k_vif_iter {
struct
ath10k_vif
*
arvif
;
};
/* used for crash-dump storage, protected by data-lock */
struct
ath10k_fw_crash_data
{
bool
crashed_since_read
;
uuid_le
uuid
;
struct
timespec
timestamp
;
__le32
registers
[
REG_DUMP_COUNT_QCA988X
];
};
struct
ath10k_debug
{
struct
dentry
*
debugfs_phy
;
struct
ath10k_target_stats
target_stats
;
u32
wmi_service_bitmap
[
WMI_SERVICE_BM_SIZE
]
;
DECLARE_BITMAP
(
wmi_service_bitmap
,
WMI_SERVICE_BM_SIZE
)
;
struct
completion
event_stats_compl
;
...
...
@@ -293,6 +306,8 @@ struct ath10k_debug {
u8
htt_max_amsdu
;
u8
htt_max_ampdu
;
struct
ath10k_fw_crash_data
*
fw_crash_data
;
};
enum
ath10k_state
{
...
...
@@ -330,6 +345,11 @@ enum ath10k_fw_features {
/* Firmware does not support P2P */
ATH10K_FW_FEATURE_NO_P2P
=
3
,
/* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature bit
* is required to be set as well.
*/
ATH10K_FW_FEATURE_WMI_10_2
=
4
,
/* keep last */
ATH10K_FW_FEATURE_COUNT
,
};
...
...
@@ -337,10 +357,32 @@ enum ath10k_fw_features {
enum
ath10k_dev_flags
{
/* Indicates that ath10k device is during CAC phase of DFS */
ATH10K_CAC_RUNNING
,
ATH10K_FLAG_FIRST_BOOT_DONE
,
ATH10K_FLAG_CORE_REGISTERED
,
};
enum
ath10k_scan_state
{
ATH10K_SCAN_IDLE
,
ATH10K_SCAN_STARTING
,
ATH10K_SCAN_RUNNING
,
ATH10K_SCAN_ABORTING
,
};
static
inline
const
char
*
ath10k_scan_state_str
(
enum
ath10k_scan_state
state
)
{
switch
(
state
)
{
case
ATH10K_SCAN_IDLE
:
return
"idle"
;
case
ATH10K_SCAN_STARTING
:
return
"starting"
;
case
ATH10K_SCAN_RUNNING
:
return
"running"
;
case
ATH10K_SCAN_ABORTING
:
return
"aborting"
;
}
return
"unknown"
;
}
struct
ath10k
{
struct
ath_common
ath_common
;
struct
ieee80211_hw
*
hw
;
...
...
@@ -368,7 +410,6 @@ struct ath10k {
bool
p2p
;
struct
{
void
*
priv
;
const
struct
ath10k_hif_ops
*
ops
;
}
hif
;
...
...
@@ -410,10 +451,9 @@ struct ath10k {
struct
completion
started
;
struct
completion
completed
;
struct
completion
on_channel
;
struct
timer_list
timeout
;
struct
delayed_work
timeout
;
enum
ath10k_scan_state
state
;
bool
is_roc
;
bool
in_progress
;
bool
aborting
;
int
vdev_id
;
int
roc_freq
;
}
scan
;
...
...
@@ -494,9 +534,21 @@ struct ath10k {
#ifdef CONFIG_ATH10K_DEBUGFS
struct
ath10k_debug
debug
;
#endif
struct
{
/* relay(fs) channel for spectral scan */
struct
rchan
*
rfs_chan_spec_scan
;
/* spectral_mode and spec_config are protected by conf_mutex */
enum
ath10k_spectral_mode
mode
;
struct
ath10k_spec_scan
config
;
}
spectral
;
/* must be last */
u8
drv_priv
[
0
]
__aligned
(
sizeof
(
void
*
));
};
struct
ath10k
*
ath10k_core_create
(
void
*
hif_priv
,
struct
device
*
dev
,
struct
ath10k
*
ath10k_core_create
(
size_t
priv_size
,
struct
device
*
dev
,
const
struct
ath10k_hif_ops
*
hif_ops
);
void
ath10k_core_destroy
(
struct
ath10k
*
ar
);
...
...
drivers/net/wireless/ath/ath10k/debug.c
浏览文件 @
59e25676
...
...
@@ -17,6 +17,9 @@
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/version.h>
#include <linux/vermagic.h>
#include <linux/vmalloc.h>
#include "core.h"
#include "debug.h"
...
...
@@ -24,25 +27,86 @@
/* ms */
#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
static
int
ath10k_printk
(
const
char
*
level
,
const
char
*
fmt
,
...)
{
struct
va_format
vaf
;
va_list
args
;
int
rtn
;
#define ATH10K_FW_CRASH_DUMP_VERSION 1
va_start
(
args
,
fmt
);
/**
* enum ath10k_fw_crash_dump_type - types of data in the dump file
* @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format
*/
enum
ath10k_fw_crash_dump_type
{
ATH10K_FW_CRASH_DUMP_REGISTERS
=
0
,
vaf
.
fmt
=
fmt
;
vaf
.
va
=
&
args
;
ATH10K_FW_CRASH_DUMP_MAX
,
}
;
rtn
=
printk
(
"%sath10k: %pV"
,
level
,
&
vaf
);
struct
ath10k_tlv_dump_data
{
/* see ath10k_fw_crash_dump_type above */
__le32
type
;
va_end
(
args
);
/* in bytes */
__le32
tlv_len
;
return
rtn
;
}
/* pad to 32-bit boundaries as needed */
u8
tlv_data
[];
}
__packed
;
struct
ath10k_dump_file_data
{
/* dump file information */
/* "ATH10K-FW-DUMP" */
char
df_magic
[
16
];
__le32
len
;
/* file dump version */
__le32
version
;
/* some info we can get from ath10k struct that might help */
u8
uuid
[
16
];
__le32
chip_id
;
/* 0 for now, in place for later hardware */
__le32
bus_type
;
__le32
target_version
;
__le32
fw_version_major
;
__le32
fw_version_minor
;
__le32
fw_version_release
;
__le32
fw_version_build
;
__le32
phy_capability
;
__le32
hw_min_tx_power
;
__le32
hw_max_tx_power
;
__le32
ht_cap_info
;
__le32
vht_cap_info
;
__le32
num_rf_chains
;
/* firmware version string */
char
fw_ver
[
ETHTOOL_FWVERS_LEN
];
/* Kernel related information */
/* time-of-day stamp */
__le64
tv_sec
;
int
ath10k_info
(
const
char
*
fmt
,
...)
/* time-of-day stamp, nano-seconds */
__le64
tv_nsec
;
/* LINUX_VERSION_CODE */
__le32
kernel_ver_code
;
/* VERMAGIC_STRING */
char
kernel_ver
[
64
];
/* room for growth w/out changing binary format */
u8
unused
[
128
];
/* struct ath10k_tlv_dump_data + more */
u8
data
[
0
];
}
__packed
;
int
ath10k_info
(
struct
ath10k
*
ar
,
const
char
*
fmt
,
...)
{
struct
va_format
vaf
=
{
.
fmt
=
fmt
,
...
...
@@ -52,7 +116,7 @@ int ath10k_info(const char *fmt, ...)
va_start
(
args
,
fmt
);
vaf
.
va
=
&
args
;
ret
=
ath10k_printk
(
KERN_INFO
,
"%pV"
,
&
vaf
);
ret
=
dev_info
(
ar
->
dev
,
"%pV"
,
&
vaf
);
trace_ath10k_log_info
(
&
vaf
);
va_end
(
args
);
...
...
@@ -60,7 +124,25 @@ int ath10k_info(const char *fmt, ...)
}
EXPORT_SYMBOL
(
ath10k_info
);
int
ath10k_err
(
const
char
*
fmt
,
...)
void
ath10k_print_driver_info
(
struct
ath10k
*
ar
)
{
ath10k_info
(
ar
,
"%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d
\n
"
,
ar
->
hw_params
.
name
,
ar
->
target_version
,
ar
->
chip_id
,
ar
->
hw
->
wiphy
->
fw_version
,
ar
->
fw_api
,
ar
->
htt
.
target_version_major
,
ar
->
htt
.
target_version_minor
);
ath10k_info
(
ar
,
"debug %d debugfs %d tracing %d dfs %d
\n
"
,
config_enabled
(
CONFIG_ATH10K_DEBUG
),
config_enabled
(
CONFIG_ATH10K_DEBUGFS
),
config_enabled
(
CONFIG_ATH10K_TRACING
),
config_enabled
(
CONFIG_ATH10K_DFS_CERTIFIED
));
}
EXPORT_SYMBOL
(
ath10k_print_driver_info
);
int
ath10k_err
(
struct
ath10k
*
ar
,
const
char
*
fmt
,
...)
{
struct
va_format
vaf
=
{
.
fmt
=
fmt
,
...
...
@@ -70,7 +152,7 @@ int ath10k_err(const char *fmt, ...)
va_start
(
args
,
fmt
);
vaf
.
va
=
&
args
;
ret
=
ath10k_printk
(
KERN_ERR
,
"%pV"
,
&
vaf
);
ret
=
dev_err
(
ar
->
dev
,
"%pV"
,
&
vaf
);
trace_ath10k_log_err
(
&
vaf
);
va_end
(
args
);
...
...
@@ -78,25 +160,21 @@ int ath10k_err(const char *fmt, ...)
}
EXPORT_SYMBOL
(
ath10k_err
);
int
ath10k_warn
(
const
char
*
fmt
,
...)
int
ath10k_warn
(
struct
ath10k
*
ar
,
const
char
*
fmt
,
...)
{
struct
va_format
vaf
=
{
.
fmt
=
fmt
,
};
va_list
args
;
int
ret
=
0
;
va_start
(
args
,
fmt
);
vaf
.
va
=
&
args
;
if
(
net_ratelimit
())
ret
=
ath10k_printk
(
KERN_WARNING
,
"%pV"
,
&
vaf
);
dev_warn_ratelimited
(
ar
->
dev
,
"%pV"
,
&
vaf
);
trace_ath10k_log_warn
(
&
vaf
);
va_end
(
args
);
return
ret
;
return
0
;
}
EXPORT_SYMBOL
(
ath10k_warn
);
...
...
@@ -115,9 +193,10 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
{
struct
ath10k
*
ar
=
file
->
private_data
;
char
*
buf
;
unsigned
int
len
=
0
,
buf_len
=
1500
;
const
char
*
status
;
unsigned
int
len
=
0
,
buf_len
=
4096
;
const
char
*
name
;
ssize_t
ret_cnt
;
bool
enabled
;
int
i
;
buf
=
kzalloc
(
buf_len
,
GFP_KERNEL
);
...
...
@@ -129,15 +208,22 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
if
(
len
>
buf_len
)
len
=
buf_len
;
for
(
i
=
0
;
i
<
WMI_SERVICE_LAST
;
i
++
)
{
if
(
WMI_SERVICE_IS_ENABLED
(
ar
->
debug
.
wmi_service_bitmap
,
i
))
status
=
"enabled"
;
else
status
=
"disabled"
;
for
(
i
=
0
;
i
<
WMI_MAX_SERVICE
;
i
++
)
{
enabled
=
test_bit
(
i
,
ar
->
debug
.
wmi_service_bitmap
);
name
=
wmi_service_name
(
i
);
if
(
!
name
)
{
if
(
enabled
)
len
+=
scnprintf
(
buf
+
len
,
buf_len
-
len
,
"%-40s %s (bit %d)
\n
"
,
"unknown"
,
"enabled"
,
i
);
continue
;
}
len
+=
scnprintf
(
buf
+
len
,
buf_len
-
len
,
"
0x%02x - %20s -
%s
\n
"
,
i
,
wmi_service_name
(
i
),
status
);
"
%-40s
%s
\n
"
,
name
,
enabled
?
"enabled"
:
"-"
);
}
ret_cnt
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
len
);
...
...
@@ -309,7 +395,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
ret
=
ath10k_wmi_request_stats
(
ar
,
WMI_REQUEST_PEER_STAT
);
if
(
ret
)
{
ath10k_warn
(
"could not request stats (%d)
\n
"
,
ret
);
ath10k_warn
(
ar
,
"could not request stats (%d)
\n
"
,
ret
);
goto
exit
;
}
...
...
@@ -527,11 +613,14 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
}
if
(
!
strcmp
(
buf
,
"soft"
))
{
ath10k_info
(
"simulating soft firmware crash
\n
"
);
ath10k_info
(
ar
,
"simulating soft firmware crash
\n
"
);
ret
=
ath10k_wmi_force_fw_hang
(
ar
,
WMI_FORCE_FW_HANG_ASSERT
,
0
);
}
else
if
(
!
strcmp
(
buf
,
"hard"
))
{
ath10k_info
(
"simulating hard firmware crash
\n
"
);
ret
=
ath10k_wmi_vdev_set_param
(
ar
,
TARGET_NUM_VDEVS
+
1
,
ath10k_info
(
ar
,
"simulating hard firmware crash
\n
"
);
/* 0x7fff is vdev id, and it is always out of range for all
* firmware variants in order to force a firmware crash.
*/
ret
=
ath10k_wmi_vdev_set_param
(
ar
,
0x7fff
,
ar
->
wmi
.
vdev_param
->
rts_threshold
,
0
);
}
else
{
ret
=
-
EINVAL
;
...
...
@@ -539,7 +628,7 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
}
if
(
ret
)
{
ath10k_warn
(
"failed to simulate firmware crash: %d
\n
"
,
ret
);
ath10k_warn
(
ar
,
"failed to simulate firmware crash: %d
\n
"
,
ret
);
goto
exit
;
}
...
...
@@ -577,6 +666,138 @@ static const struct file_operations fops_chip_id = {
.
llseek
=
default_llseek
,
};
struct
ath10k_fw_crash_data
*
ath10k_debug_get_new_fw_crash_data
(
struct
ath10k
*
ar
)
{
struct
ath10k_fw_crash_data
*
crash_data
=
ar
->
debug
.
fw_crash_data
;
lockdep_assert_held
(
&
ar
->
data_lock
);
crash_data
->
crashed_since_read
=
true
;
uuid_le_gen
(
&
crash_data
->
uuid
);
getnstimeofday
(
&
crash_data
->
timestamp
);
return
crash_data
;
}
EXPORT_SYMBOL
(
ath10k_debug_get_new_fw_crash_data
);
static
struct
ath10k_dump_file_data
*
ath10k_build_dump_file
(
struct
ath10k
*
ar
)
{
struct
ath10k_fw_crash_data
*
crash_data
=
ar
->
debug
.
fw_crash_data
;
struct
ath10k_dump_file_data
*
dump_data
;
struct
ath10k_tlv_dump_data
*
dump_tlv
;
int
hdr_len
=
sizeof
(
*
dump_data
);
unsigned
int
len
,
sofar
=
0
;
unsigned
char
*
buf
;
len
=
hdr_len
;
len
+=
sizeof
(
*
dump_tlv
)
+
sizeof
(
crash_data
->
registers
);
sofar
+=
hdr_len
;
/* This is going to get big when we start dumping FW RAM and such,
* so go ahead and use vmalloc.
*/
buf
=
vzalloc
(
len
);
if
(
!
buf
)
return
NULL
;
spin_lock_bh
(
&
ar
->
data_lock
);
if
(
!
crash_data
->
crashed_since_read
)
{
spin_unlock_bh
(
&
ar
->
data_lock
);
vfree
(
buf
);
return
NULL
;
}
dump_data
=
(
struct
ath10k_dump_file_data
*
)(
buf
);
strlcpy
(
dump_data
->
df_magic
,
"ATH10K-FW-DUMP"
,
sizeof
(
dump_data
->
df_magic
));
dump_data
->
len
=
cpu_to_le32
(
len
);
dump_data
->
version
=
cpu_to_le32
(
ATH10K_FW_CRASH_DUMP_VERSION
);
memcpy
(
dump_data
->
uuid
,
&
crash_data
->
uuid
,
sizeof
(
dump_data
->
uuid
));
dump_data
->
chip_id
=
cpu_to_le32
(
ar
->
chip_id
);
dump_data
->
bus_type
=
cpu_to_le32
(
0
);
dump_data
->
target_version
=
cpu_to_le32
(
ar
->
target_version
);
dump_data
->
fw_version_major
=
cpu_to_le32
(
ar
->
fw_version_major
);
dump_data
->
fw_version_minor
=
cpu_to_le32
(
ar
->
fw_version_minor
);
dump_data
->
fw_version_release
=
cpu_to_le32
(
ar
->
fw_version_release
);
dump_data
->
fw_version_build
=
cpu_to_le32
(
ar
->
fw_version_build
);
dump_data
->
phy_capability
=
cpu_to_le32
(
ar
->
phy_capability
);
dump_data
->
hw_min_tx_power
=
cpu_to_le32
(
ar
->
hw_min_tx_power
);
dump_data
->
hw_max_tx_power
=
cpu_to_le32
(
ar
->
hw_max_tx_power
);
dump_data
->
ht_cap_info
=
cpu_to_le32
(
ar
->
ht_cap_info
);
dump_data
->
vht_cap_info
=
cpu_to_le32
(
ar
->
vht_cap_info
);
dump_data
->
num_rf_chains
=
cpu_to_le32
(
ar
->
num_rf_chains
);
strlcpy
(
dump_data
->
fw_ver
,
ar
->
hw
->
wiphy
->
fw_version
,
sizeof
(
dump_data
->
fw_ver
));
dump_data
->
kernel_ver_code
=
cpu_to_le32
(
LINUX_VERSION_CODE
);
strlcpy
(
dump_data
->
kernel_ver
,
VERMAGIC_STRING
,
sizeof
(
dump_data
->
kernel_ver
));
dump_data
->
tv_sec
=
cpu_to_le64
(
crash_data
->
timestamp
.
tv_sec
);
dump_data
->
tv_nsec
=
cpu_to_le64
(
crash_data
->
timestamp
.
tv_nsec
);
/* Gather crash-dump */
dump_tlv
=
(
struct
ath10k_tlv_dump_data
*
)(
buf
+
sofar
);
dump_tlv
->
type
=
cpu_to_le32
(
ATH10K_FW_CRASH_DUMP_REGISTERS
);
dump_tlv
->
tlv_len
=
cpu_to_le32
(
sizeof
(
crash_data
->
registers
));
memcpy
(
dump_tlv
->
tlv_data
,
&
crash_data
->
registers
,
sizeof
(
crash_data
->
registers
));
sofar
+=
sizeof
(
*
dump_tlv
)
+
sizeof
(
crash_data
->
registers
);
ar
->
debug
.
fw_crash_data
->
crashed_since_read
=
false
;
spin_unlock_bh
(
&
ar
->
data_lock
);
return
dump_data
;
}
static
int
ath10k_fw_crash_dump_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
ath10k
*
ar
=
inode
->
i_private
;
struct
ath10k_dump_file_data
*
dump
;
dump
=
ath10k_build_dump_file
(
ar
);
if
(
!
dump
)
return
-
ENODATA
;
file
->
private_data
=
dump
;
return
0
;
}
static
ssize_t
ath10k_fw_crash_dump_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k_dump_file_data
*
dump_file
=
file
->
private_data
;
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
dump_file
,
le32_to_cpu
(
dump_file
->
len
));
}
static
int
ath10k_fw_crash_dump_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
vfree
(
file
->
private_data
);
return
0
;
}
static
const
struct
file_operations
fops_fw_crash_dump
=
{
.
open
=
ath10k_fw_crash_dump_open
,
.
read
=
ath10k_fw_crash_dump_read
,
.
release
=
ath10k_fw_crash_dump_release
,
.
owner
=
THIS_MODULE
,
.
llseek
=
default_llseek
,
};
static
int
ath10k_debug_htt_stats_req
(
struct
ath10k
*
ar
)
{
u64
cookie
;
...
...
@@ -596,7 +817,7 @@ static int ath10k_debug_htt_stats_req(struct ath10k *ar)
ret
=
ath10k_htt_h2t_stats_req
(
&
ar
->
htt
,
ar
->
debug
.
htt_stats_mask
,
cookie
);
if
(
ret
)
{
ath10k_warn
(
"failed to send htt stats request: %d
\n
"
,
ret
);
ath10k_warn
(
ar
,
"failed to send htt stats request: %d
\n
"
,
ret
);
return
ret
;
}
...
...
@@ -770,7 +991,7 @@ static ssize_t ath10k_write_fw_dbglog(struct file *file,
if
(
ar
->
state
==
ATH10K_STATE_ON
)
{
ret
=
ath10k_wmi_dbglog_cfg
(
ar
,
ar
->
debug
.
fw_dbglog_mask
);
if
(
ret
)
{
ath10k_warn
(
"dbglog cfg failed from debugfs: %d
\n
"
,
ath10k_warn
(
ar
,
"dbglog cfg failed from debugfs: %d
\n
"
,
ret
);
goto
exit
;
}
...
...
@@ -801,13 +1022,14 @@ int ath10k_debug_start(struct ath10k *ar)
ret
=
ath10k_debug_htt_stats_req
(
ar
);
if
(
ret
)
/* continue normally anyway, this isn't serious */
ath10k_warn
(
"failed to start htt stats workqueue: %d
\n
"
,
ret
);
ath10k_warn
(
ar
,
"failed to start htt stats workqueue: %d
\n
"
,
ret
);
if
(
ar
->
debug
.
fw_dbglog_mask
)
{
ret
=
ath10k_wmi_dbglog_cfg
(
ar
,
ar
->
debug
.
fw_dbglog_mask
);
if
(
ret
)
/* not serious */
ath10k_warn
(
"failed to enable dbglog during start: %d"
,
ath10k_warn
(
ar
,
"failed to enable dbglog during start: %d"
,
ret
);
}
...
...
@@ -910,11 +1132,20 @@ static const struct file_operations fops_dfs_stats = {
int
ath10k_debug_create
(
struct
ath10k
*
ar
)
{
int
ret
;
ar
->
debug
.
fw_crash_data
=
vzalloc
(
sizeof
(
*
ar
->
debug
.
fw_crash_data
));
if
(
!
ar
->
debug
.
fw_crash_data
)
{
ret
=
-
ENOMEM
;
goto
err
;
}
ar
->
debug
.
debugfs_phy
=
debugfs_create_dir
(
"ath10k"
,
ar
->
hw
->
wiphy
->
debugfsdir
);
if
(
!
ar
->
debug
.
debugfs_phy
)
return
-
ENOMEM
;
if
(
!
ar
->
debug
.
debugfs_phy
)
{
ret
=
-
ENOMEM
;
goto
err_free_fw_crash_data
;
}
INIT_DELAYED_WORK
(
&
ar
->
debug
.
htt_stats_dwork
,
ath10k_debug_htt_stats_dwork
);
...
...
@@ -930,6 +1161,9 @@ int ath10k_debug_create(struct ath10k *ar)
debugfs_create_file
(
"simulate_fw_crash"
,
S_IRUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_simulate_fw_crash
);
debugfs_create_file
(
"fw_crash_dump"
,
S_IRUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_fw_crash_dump
);
debugfs_create_file
(
"chip_id"
,
S_IRUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_chip_id
);
...
...
@@ -958,17 +1192,25 @@ int ath10k_debug_create(struct ath10k *ar)
}
return
0
;
err_free_fw_crash_data:
vfree
(
ar
->
debug
.
fw_crash_data
);
err:
return
ret
;
}
void
ath10k_debug_destroy
(
struct
ath10k
*
ar
)
{
vfree
(
ar
->
debug
.
fw_crash_data
);
cancel_delayed_work_sync
(
&
ar
->
debug
.
htt_stats_dwork
);
}
#endif
/* CONFIG_ATH10K_DEBUGFS */
#ifdef CONFIG_ATH10K_DEBUG
void
ath10k_dbg
(
enum
ath10k_debug_mask
mask
,
const
char
*
fmt
,
...)
void
ath10k_dbg
(
struct
ath10k
*
ar
,
enum
ath10k_debug_mask
mask
,
const
char
*
fmt
,
...)
{
struct
va_format
vaf
;
va_list
args
;
...
...
@@ -979,7 +1221,7 @@ void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...)
vaf
.
va
=
&
args
;
if
(
ath10k_debug_mask
&
mask
)
ath10k_printk
(
KERN_DEBUG
,
"%pV"
,
&
vaf
);
dev_printk
(
KERN_DEBUG
,
ar
->
dev
,
"%pV"
,
&
vaf
);
trace_ath10k_log_dbg
(
mask
,
&
vaf
);
...
...
@@ -987,13 +1229,14 @@ void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...)
}
EXPORT_SYMBOL
(
ath10k_dbg
);
void
ath10k_dbg_dump
(
enum
ath10k_debug_mask
mask
,
void
ath10k_dbg_dump
(
struct
ath10k
*
ar
,
enum
ath10k_debug_mask
mask
,
const
char
*
msg
,
const
char
*
prefix
,
const
void
*
buf
,
size_t
len
)
{
if
(
ath10k_debug_mask
&
mask
)
{
if
(
msg
)
ath10k_dbg
(
mask
,
"%s
\n
"
,
msg
);
ath10k_dbg
(
ar
,
mask
,
"%s
\n
"
,
msg
);
print_hex_dump_bytes
(
prefix
,
DUMP_PREFIX_OFFSET
,
buf
,
len
);
}
...
...
drivers/net/wireless/ath/ath10k/debug.h
浏览文件 @
59e25676
...
...
@@ -39,9 +39,10 @@ enum ath10k_debug_mask {
extern
unsigned
int
ath10k_debug_mask
;
__printf
(
1
,
2
)
int
ath10k_info
(
const
char
*
fmt
,
...);
__printf
(
1
,
2
)
int
ath10k_err
(
const
char
*
fmt
,
...);
__printf
(
1
,
2
)
int
ath10k_warn
(
const
char
*
fmt
,
...);
__printf
(
2
,
3
)
int
ath10k_info
(
struct
ath10k
*
ar
,
const
char
*
fmt
,
...);
__printf
(
2
,
3
)
int
ath10k_err
(
struct
ath10k
*
ar
,
const
char
*
fmt
,
...);
__printf
(
2
,
3
)
int
ath10k_warn
(
struct
ath10k
*
ar
,
const
char
*
fmt
,
...);
void
ath10k_print_driver_info
(
struct
ath10k
*
ar
);
#ifdef CONFIG_ATH10K_DEBUGFS
int
ath10k_debug_start
(
struct
ath10k
*
ar
);
...
...
@@ -53,6 +54,10 @@ void ath10k_debug_read_service_map(struct ath10k *ar,
size_t
map_size
);
void
ath10k_debug_read_target_stats
(
struct
ath10k
*
ar
,
struct
wmi_stats_event
*
ev
);
struct
ath10k_fw_crash_data
*
ath10k_debug_get_new_fw_crash_data
(
struct
ath10k
*
ar
);
void
ath10k_debug_dbglog_add
(
struct
ath10k
*
ar
,
u8
*
buffer
,
int
len
);
#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
...
...
@@ -86,25 +91,40 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
{
}
static
inline
void
ath10k_debug_dbglog_add
(
struct
ath10k
*
ar
,
u8
*
buffer
,
int
len
)
{
}
static
inline
struct
ath10k_fw_crash_data
*
ath10k_debug_get_new_fw_crash_data
(
struct
ath10k
*
ar
)
{
return
NULL
;
}
#define ATH10K_DFS_STAT_INC(ar, c) do { } while (0)
#endif
/* CONFIG_ATH10K_DEBUGFS */
#ifdef CONFIG_ATH10K_DEBUG
__printf
(
2
,
3
)
void
ath10k_dbg
(
enum
ath10k_debug_mask
mask
,
__printf
(
3
,
4
)
void
ath10k_dbg
(
struct
ath10k
*
ar
,
enum
ath10k_debug_mask
mask
,
const
char
*
fmt
,
...);
void
ath10k_dbg_dump
(
enum
ath10k_debug_mask
mask
,
void
ath10k_dbg_dump
(
struct
ath10k
*
ar
,
enum
ath10k_debug_mask
mask
,
const
char
*
msg
,
const
char
*
prefix
,
const
void
*
buf
,
size_t
len
);
#else
/* CONFIG_ATH10K_DEBUG */
static
inline
int
ath10k_dbg
(
enum
ath10k_debug_mask
dbg_mask
,
static
inline
int
ath10k_dbg
(
struct
ath10k
*
ar
,
enum
ath10k_debug_mask
dbg_mask
,
const
char
*
fmt
,
...)
{
return
0
;
}
static
inline
void
ath10k_dbg_dump
(
enum
ath10k_debug_mask
mask
,
static
inline
void
ath10k_dbg_dump
(
struct
ath10k
*
ar
,
enum
ath10k_debug_mask
mask
,
const
char
*
msg
,
const
char
*
prefix
,
const
void
*
buf
,
size_t
len
)
{
...
...
drivers/net/wireless/ath/ath10k/htc.c
浏览文件 @
59e25676
...
...
@@ -46,7 +46,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
skb
=
dev_alloc_skb
(
ATH10K_HTC_CONTROL_BUFFER_SIZE
);
if
(
!
skb
)
{
ath10k_warn
(
"Unable to allocate ctrl skb
\n
"
);
ath10k_warn
(
ar
,
"Unable to allocate ctrl skb
\n
"
);
return
NULL
;
}
...
...
@@ -56,7 +56,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
skb_cb
=
ATH10K_SKB_CB
(
skb
);
memset
(
skb_cb
,
0
,
sizeof
(
*
skb_cb
));
ath10k_dbg
(
ATH10K_DBG_HTC
,
"%s: skb %p
\n
"
,
__func__
,
skb
);
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"%s: skb %p
\n
"
,
__func__
,
skb
);
return
skb
;
}
...
...
@@ -72,13 +72,15 @@ static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
static
void
ath10k_htc_notify_tx_completion
(
struct
ath10k_htc_ep
*
ep
,
struct
sk_buff
*
skb
)
{
ath10k_dbg
(
ATH10K_DBG_HTC
,
"%s: ep %d skb %p
\n
"
,
__func__
,
struct
ath10k
*
ar
=
ep
->
htc
->
ar
;
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"%s: ep %d skb %p
\n
"
,
__func__
,
ep
->
eid
,
skb
);
ath10k_htc_restore_tx_skb
(
ep
->
htc
,
skb
);
if
(
!
ep
->
ep_ops
.
ep_tx_complete
)
{
ath10k_warn
(
"no tx handler for eid %d
\n
"
,
ep
->
eid
);
ath10k_warn
(
ar
,
"no tx handler for eid %d
\n
"
,
ep
->
eid
);
dev_kfree_skb_any
(
skb
);
return
;
}
...
...
@@ -89,12 +91,14 @@ static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
/* assumes tx_lock is held */
static
bool
ath10k_htc_ep_need_credit_update
(
struct
ath10k_htc_ep
*
ep
)
{
struct
ath10k
*
ar
=
ep
->
htc
->
ar
;
if
(
!
ep
->
tx_credit_flow_enabled
)
return
false
;
if
(
ep
->
tx_credits
>=
ep
->
tx_credits_per_max_message
)
return
false
;
ath10k_dbg
(
ATH10K_DBG_HTC
,
"HTC: endpoint %d needs credit update
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"HTC: endpoint %d needs credit update
\n
"
,
ep
->
eid
);
return
true
;
}
...
...
@@ -123,6 +127,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
enum
ath10k_htc_ep_id
eid
,
struct
sk_buff
*
skb
)
{
struct
ath10k
*
ar
=
htc
->
ar
;
struct
ath10k_htc_ep
*
ep
=
&
htc
->
endpoint
[
eid
];
struct
ath10k_skb_cb
*
skb_cb
=
ATH10K_SKB_CB
(
skb
);
struct
ath10k_hif_sg_item
sg_item
;
...
...
@@ -134,18 +139,10 @@ int ath10k_htc_send(struct ath10k_htc *htc,
return
-
ECOMM
;
if
(
eid
>=
ATH10K_HTC_EP_COUNT
)
{
ath10k_warn
(
"Invalid endpoint id: %d
\n
"
,
eid
);
ath10k_warn
(
ar
,
"Invalid endpoint id: %d
\n
"
,
eid
);
return
-
ENOENT
;
}
/* FIXME: This looks ugly, can we fix it? */
spin_lock_bh
(
&
htc
->
tx_lock
);
if
(
htc
->
stopped
)
{
spin_unlock_bh
(
&
htc
->
tx_lock
);
return
-
ESHUTDOWN
;
}
spin_unlock_bh
(
&
htc
->
tx_lock
);
skb_push
(
skb
,
sizeof
(
struct
ath10k_htc_hdr
));
if
(
ep
->
tx_credit_flow_enabled
)
{
...
...
@@ -157,7 +154,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
goto
err_pull
;
}
ep
->
tx_credits
-=
credits
;
ath10k_dbg
(
ATH10K_DBG_HTC
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"htc ep %d consumed %d credits (total %d)
\n
"
,
eid
,
credits
,
ep
->
tx_credits
);
spin_unlock_bh
(
&
htc
->
tx_lock
);
...
...
@@ -188,7 +185,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
if
(
ep
->
tx_credit_flow_enabled
)
{
spin_lock_bh
(
&
htc
->
tx_lock
);
ep
->
tx_credits
+=
credits
;
ath10k_dbg
(
ATH10K_DBG_HTC
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"htc ep %d reverted %d credits back (total %d)
\n
"
,
eid
,
credits
,
ep
->
tx_credits
);
spin_unlock_bh
(
&
htc
->
tx_lock
);
...
...
@@ -227,11 +224,12 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc,
int
len
,
enum
ath10k_htc_ep_id
eid
)
{
struct
ath10k
*
ar
=
htc
->
ar
;
struct
ath10k_htc_ep
*
ep
;
int
i
,
n_reports
;
if
(
len
%
sizeof
(
*
report
))
ath10k_warn
(
"Uneven credit report len %d"
,
len
);
ath10k_warn
(
ar
,
"Uneven credit report len %d"
,
len
);
n_reports
=
len
/
sizeof
(
*
report
);
...
...
@@ -243,7 +241,7 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc,
ep
=
&
htc
->
endpoint
[
report
->
eid
];
ep
->
tx_credits
+=
report
->
credits
;
ath10k_dbg
(
ATH10K_DBG_HTC
,
"htc ep %d got %d credits (total %d)
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"htc ep %d got %d credits (total %d)
\n
"
,
report
->
eid
,
report
->
credits
,
ep
->
tx_credits
);
if
(
ep
->
ep_ops
.
ep_tx_credits
)
{
...
...
@@ -260,6 +258,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
int
length
,
enum
ath10k_htc_ep_id
src_eid
)
{
struct
ath10k
*
ar
=
htc
->
ar
;
int
status
=
0
;
struct
ath10k_htc_record
*
record
;
u8
*
orig_buffer
;
...
...
@@ -279,7 +278,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
if
(
record
->
hdr
.
len
>
length
)
{
/* no room left in buffer for record */
ath10k_warn
(
"Invalid record length: %d
\n
"
,
ath10k_warn
(
ar
,
"Invalid record length: %d
\n
"
,
record
->
hdr
.
len
);
status
=
-
EINVAL
;
break
;
...
...
@@ -289,7 +288,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
case
ATH10K_HTC_RECORD_CREDITS
:
len
=
sizeof
(
struct
ath10k_htc_credit_report
);
if
(
record
->
hdr
.
len
<
len
)
{
ath10k_warn
(
"Credit report too long
\n
"
);
ath10k_warn
(
ar
,
"Credit report too long
\n
"
);
status
=
-
EINVAL
;
break
;
}
...
...
@@ -299,7 +298,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
src_eid
);
break
;
default:
ath10k_warn
(
"Unhandled record: id:%d length:%d
\n
"
,
ath10k_warn
(
ar
,
"Unhandled record: id:%d length:%d
\n
"
,
record
->
hdr
.
id
,
record
->
hdr
.
len
);
break
;
}
...
...
@@ -313,7 +312,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
}
if
(
status
)
ath10k_dbg_dump
(
ATH10K_DBG_HTC
,
"htc rx bad trailer"
,
""
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTC
,
"htc rx bad trailer"
,
""
,
orig_buffer
,
orig_length
);
return
status
;
...
...
@@ -339,8 +338,8 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
eid
=
hdr
->
eid
;
if
(
eid
>=
ATH10K_HTC_EP_COUNT
)
{
ath10k_warn
(
"HTC Rx: invalid eid %d
\n
"
,
eid
);
ath10k_dbg_dump
(
ATH10K_DBG_HTC
,
"htc bad header"
,
""
,
ath10k_warn
(
ar
,
"HTC Rx: invalid eid %d
\n
"
,
eid
);
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTC
,
"htc bad header"
,
""
,
hdr
,
sizeof
(
*
hdr
));
status
=
-
EINVAL
;
goto
out
;
...
...
@@ -360,19 +359,19 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
payload_len
=
__le16_to_cpu
(
hdr
->
len
);
if
(
payload_len
+
sizeof
(
*
hdr
)
>
ATH10K_HTC_MAX_LEN
)
{
ath10k_warn
(
"HTC rx frame too long, len: %zu
\n
"
,
ath10k_warn
(
ar
,
"HTC rx frame too long, len: %zu
\n
"
,
payload_len
+
sizeof
(
*
hdr
));
ath10k_dbg_dump
(
ATH10K_DBG_HTC
,
"htc bad rx pkt len"
,
""
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTC
,
"htc bad rx pkt len"
,
""
,
hdr
,
sizeof
(
*
hdr
));
status
=
-
EINVAL
;
goto
out
;
}
if
(
skb
->
len
<
payload_len
)
{
ath10k_dbg
(
ATH10K_DBG_HTC
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"HTC Rx: insufficient length, got %d, expected %d
\n
"
,
skb
->
len
,
payload_len
);
ath10k_dbg_dump
(
ATH10K_DBG_HTC
,
"htc bad rx pkt len"
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTC
,
"htc bad rx pkt len"
,
""
,
hdr
,
sizeof
(
*
hdr
));
status
=
-
EINVAL
;
goto
out
;
...
...
@@ -388,7 +387,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
if
((
trailer_len
<
min_len
)
||
(
trailer_len
>
payload_len
))
{
ath10k_warn
(
"Invalid trailer length: %d
\n
"
,
ath10k_warn
(
ar
,
"Invalid trailer length: %d
\n
"
,
trailer_len
);
status
=
-
EPROTO
;
goto
out
;
...
...
@@ -421,7 +420,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
* this is a fatal error, target should not be
* sending unsolicited messages on the ep 0
*/
ath10k_warn
(
"HTC rx ctrl still processing
\n
"
);
ath10k_warn
(
ar
,
"HTC rx ctrl still processing
\n
"
);
status
=
-
EINVAL
;
complete
(
&
htc
->
ctl_resp
);
goto
out
;
...
...
@@ -442,7 +441,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
goto
out
;
}
ath10k_dbg
(
ATH10K_DBG_HTC
,
"htc rx completion ep %d skb %p
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"htc rx completion ep %d skb %p
\n
"
,
eid
,
skb
);
ep
->
ep_ops
.
ep_rx_complete
(
ar
,
skb
);
...
...
@@ -459,7 +458,7 @@ static void ath10k_htc_control_rx_complete(struct ath10k *ar,
{
/* This is unexpected. FW is not supposed to send regular rx on this
* endpoint. */
ath10k_warn
(
"unexpected htc rx
\n
"
);
ath10k_warn
(
ar
,
"unexpected htc rx
\n
"
);
kfree_skb
(
skb
);
}
...
...
@@ -546,6 +545,7 @@ static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
int
ath10k_htc_wait_target
(
struct
ath10k_htc
*
htc
)
{
struct
ath10k
*
ar
=
htc
->
ar
;
int
i
,
status
=
0
;
struct
ath10k_htc_svc_conn_req
conn_req
;
struct
ath10k_htc_svc_conn_resp
conn_resp
;
...
...
@@ -563,7 +563,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
* iomap writes unmasking PCI CE irqs aren't propagated
* properly in KVM PCI-passthrough sometimes.
*/
ath10k_warn
(
"failed to receive control response completion, polling..
\n
"
);
ath10k_warn
(
ar
,
"failed to receive control response completion, polling..
\n
"
);
for
(
i
=
0
;
i
<
CE_COUNT
;
i
++
)
ath10k_hif_send_complete_check
(
htc
->
ar
,
i
,
1
);
...
...
@@ -576,12 +576,12 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
}
if
(
status
<
0
)
{
ath10k_err
(
"ctl_resp never came in (%d)
\n
"
,
status
);
ath10k_err
(
ar
,
"ctl_resp never came in (%d)
\n
"
,
status
);
return
status
;
}
if
(
htc
->
control_resp_len
<
sizeof
(
msg
->
hdr
)
+
sizeof
(
msg
->
ready
))
{
ath10k_err
(
"Invalid HTC ready msg len:%d
\n
"
,
ath10k_err
(
ar
,
"Invalid HTC ready msg len:%d
\n
"
,
htc
->
control_resp_len
);
return
-
ECOMM
;
}
...
...
@@ -592,21 +592,21 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
credit_size
=
__le16_to_cpu
(
msg
->
ready
.
credit_size
);
if
(
message_id
!=
ATH10K_HTC_MSG_READY_ID
)
{
ath10k_err
(
"Invalid HTC ready msg: 0x%x
\n
"
,
message_id
);
ath10k_err
(
ar
,
"Invalid HTC ready msg: 0x%x
\n
"
,
message_id
);
return
-
ECOMM
;
}
htc
->
total_transmit_credits
=
credit_count
;
htc
->
target_credit_size
=
credit_size
;
ath10k_dbg
(
ATH10K_DBG_HTC
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"Target ready! transmit resources: %d size:%d
\n
"
,
htc
->
total_transmit_credits
,
htc
->
target_credit_size
);
if
((
htc
->
total_transmit_credits
==
0
)
||
(
htc
->
target_credit_size
==
0
))
{
ath10k_err
(
"Invalid credit size received
\n
"
);
ath10k_err
(
ar
,
"Invalid credit size received
\n
"
);
return
-
ECOMM
;
}
...
...
@@ -623,7 +623,8 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
/* connect fake service */
status
=
ath10k_htc_connect_service
(
htc
,
&
conn_req
,
&
conn_resp
);
if
(
status
)
{
ath10k_err
(
"could not connect to htc service (%d)
\n
"
,
status
);
ath10k_err
(
ar
,
"could not connect to htc service (%d)
\n
"
,
status
);
return
status
;
}
...
...
@@ -634,6 +635,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
struct
ath10k_htc_svc_conn_req
*
conn_req
,
struct
ath10k_htc_svc_conn_resp
*
conn_resp
)
{
struct
ath10k
*
ar
=
htc
->
ar
;
struct
ath10k_htc_msg
*
msg
;
struct
ath10k_htc_conn_svc
*
req_msg
;
struct
ath10k_htc_conn_svc_response
resp_msg_dummy
;
...
...
@@ -659,13 +661,13 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
tx_alloc
=
ath10k_htc_get_credit_allocation
(
htc
,
conn_req
->
service_id
);
if
(
!
tx_alloc
)
ath10k_dbg
(
ATH10K_DBG_BOOT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"boot htc service %s does not allocate target credits
\n
"
,
htc_service_name
(
conn_req
->
service_id
));
skb
=
ath10k_htc_build_tx_ctrl_skb
(
htc
->
ar
);
if
(
!
skb
)
{
ath10k_err
(
"Failed to allocate HTC packet
\n
"
);
ath10k_err
(
ar
,
"Failed to allocate HTC packet
\n
"
);
return
-
ENOMEM
;
}
...
...
@@ -703,7 +705,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
if
(
status
<=
0
)
{
if
(
status
==
0
)
status
=
-
ETIMEDOUT
;
ath10k_err
(
"Service connect timeout: %d
\n
"
,
status
);
ath10k_err
(
ar
,
"Service connect timeout: %d
\n
"
,
status
);
return
status
;
}
...
...
@@ -716,11 +718,11 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
if
((
message_id
!=
ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID
)
||
(
htc
->
control_resp_len
<
sizeof
(
msg
->
hdr
)
+
sizeof
(
msg
->
connect_service_response
)))
{
ath10k_err
(
"Invalid resp message ID 0x%x"
,
message_id
);
ath10k_err
(
ar
,
"Invalid resp message ID 0x%x"
,
message_id
);
return
-
EPROTO
;
}
ath10k_dbg
(
ATH10K_DBG_HTC
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x
\n
"
,
htc_service_name
(
service_id
),
resp_msg
->
status
,
resp_msg
->
eid
);
...
...
@@ -729,7 +731,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
/* check response status */
if
(
resp_msg
->
status
!=
ATH10K_HTC_CONN_SVC_STATUS_SUCCESS
)
{
ath10k_err
(
"HTC Service %s connect request failed: 0x%x)
\n
"
,
ath10k_err
(
ar
,
"HTC Service %s connect request failed: 0x%x)
\n
"
,
htc_service_name
(
service_id
),
resp_msg
->
status
);
return
-
EPROTO
;
...
...
@@ -780,18 +782,18 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
if
(
status
)
return
status
;
ath10k_dbg
(
ATH10K_DBG_BOOT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"boot htc service '%s' ul pipe %d dl pipe %d eid %d ready
\n
"
,
htc_service_name
(
ep
->
service_id
),
ep
->
ul_pipe_id
,
ep
->
dl_pipe_id
,
ep
->
eid
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"boot htc ep %d ul polled %d dl polled %d
\n
"
,
ep
->
eid
,
ep
->
ul_is_polled
,
ep
->
dl_is_polled
);
if
(
disable_credit_flow_ctrl
&&
ep
->
tx_credit_flow_enabled
)
{
ep
->
tx_credit_flow_enabled
=
false
;
ath10k_dbg
(
ATH10K_DBG_BOOT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"boot htc service '%s' eid %d TX flow control disabled
\n
"
,
htc_service_name
(
ep
->
service_id
),
assigned_eid
);
}
...
...
@@ -799,13 +801,13 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
return
status
;
}
struct
sk_buff
*
ath10k_htc_alloc_skb
(
int
size
)
struct
sk_buff
*
ath10k_htc_alloc_skb
(
struct
ath10k
*
ar
,
int
size
)
{
struct
sk_buff
*
skb
;
skb
=
dev_alloc_skb
(
size
+
sizeof
(
struct
ath10k_htc_hdr
));
if
(
!
skb
)
{
ath10k_warn
(
"could not allocate HTC tx skb
\n
"
);
ath10k_warn
(
ar
,
"could not allocate HTC tx skb
\n
"
);
return
NULL
;
}
...
...
@@ -813,13 +815,14 @@ struct sk_buff *ath10k_htc_alloc_skb(int size)
/* FW/HTC requires 4-byte aligned streams */
if
(
!
IS_ALIGNED
((
unsigned
long
)
skb
->
data
,
4
))
ath10k_warn
(
"Unaligned HTC tx skb
\n
"
);
ath10k_warn
(
ar
,
"Unaligned HTC tx skb
\n
"
);
return
skb
;
}
int
ath10k_htc_start
(
struct
ath10k_htc
*
htc
)
{
struct
ath10k
*
ar
=
htc
->
ar
;
struct
sk_buff
*
skb
;
int
status
=
0
;
struct
ath10k_htc_msg
*
msg
;
...
...
@@ -835,7 +838,7 @@ int ath10k_htc_start(struct ath10k_htc *htc)
msg
->
hdr
.
message_id
=
__cpu_to_le16
(
ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID
);
ath10k_dbg
(
ATH10K_DBG_HTC
,
"HTC is using TX credit flow control
\n
"
);
ath10k_dbg
(
ar
,
ATH10K_DBG_HTC
,
"HTC is using TX credit flow control
\n
"
);
status
=
ath10k_htc_send
(
htc
,
ATH10K_HTC_EP_0
,
skb
);
if
(
status
)
{
...
...
@@ -846,13 +849,6 @@ int ath10k_htc_start(struct ath10k_htc *htc)
return
0
;
}
void
ath10k_htc_stop
(
struct
ath10k_htc
*
htc
)
{
spin_lock_bh
(
&
htc
->
tx_lock
);
htc
->
stopped
=
true
;
spin_unlock_bh
(
&
htc
->
tx_lock
);
}
/* registered target arrival callback from the HIF layer */
int
ath10k_htc_init
(
struct
ath10k
*
ar
)
{
...
...
@@ -862,7 +858,6 @@ int ath10k_htc_init(struct ath10k *ar)
spin_lock_init
(
&
htc
->
tx_lock
);
htc
->
stopped
=
false
;
ath10k_htc_reset_endpoint_states
(
htc
);
/* setup HIF layer callbacks */
...
...
drivers/net/wireless/ath/ath10k/htc.h
浏览文件 @
59e25676
...
...
@@ -332,7 +332,7 @@ struct ath10k_htc {
struct
ath10k
*
ar
;
struct
ath10k_htc_ep
endpoint
[
ATH10K_HTC_EP_COUNT
];
/* protects endpoint
and stopped field
s */
/* protects endpoints */
spinlock_t
tx_lock
;
struct
ath10k_htc_ops
htc_ops
;
...
...
@@ -345,8 +345,6 @@ struct ath10k_htc {
int
total_transmit_credits
;
struct
ath10k_htc_svc_tx_credits
service_tx_alloc
[
ATH10K_HTC_EP_COUNT
];
int
target_credit_size
;
bool
stopped
;
};
int
ath10k_htc_init
(
struct
ath10k
*
ar
);
...
...
@@ -357,7 +355,6 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
struct
ath10k_htc_svc_conn_resp
*
conn_resp
);
int
ath10k_htc_send
(
struct
ath10k_htc
*
htc
,
enum
ath10k_htc_ep_id
eid
,
struct
sk_buff
*
packet
);
void
ath10k_htc_stop
(
struct
ath10k_htc
*
htc
);
struct
sk_buff
*
ath10k_htc_alloc_skb
(
int
size
);
struct
sk_buff
*
ath10k_htc_alloc_skb
(
struct
ath10k
*
ar
,
int
size
);
#endif
drivers/net/wireless/ath/ath10k/htt.c
浏览文件 @
59e25676
...
...
@@ -74,12 +74,14 @@ int ath10k_htt_init(struct ath10k *ar)
static
int
ath10k_htt_verify_version
(
struct
ath10k_htt
*
htt
)
{
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"htt target version %d.%d
\n
"
,
struct
ath10k
*
ar
=
htt
->
ar
;
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"htt target version %d.%d
\n
"
,
htt
->
target_version_major
,
htt
->
target_version_minor
);
if
(
htt
->
target_version_major
!=
2
&&
htt
->
target_version_major
!=
3
)
{
ath10k_err
(
"unsupported htt major version %d. supported versions are 2 and 3
\n
"
,
ath10k_err
(
ar
,
"unsupported htt major version %d. supported versions are 2 and 3
\n
"
,
htt
->
target_version_major
);
return
-
ENOTSUPP
;
}
...
...
@@ -89,6 +91,7 @@ static int ath10k_htt_verify_version(struct ath10k_htt *htt)
int
ath10k_htt_setup
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
int
status
;
init_completion
(
&
htt
->
target_version_received
);
...
...
@@ -100,7 +103,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
status
=
wait_for_completion_timeout
(
&
htt
->
target_version_received
,
HTT_TARGET_VERSION_TIMEOUT_HZ
);
if
(
status
<=
0
)
{
ath10k_warn
(
"htt version request timed out
\n
"
);
ath10k_warn
(
ar
,
"htt version request timed out
\n
"
);
return
-
ETIMEDOUT
;
}
...
...
drivers/net/wireless/ath/ath10k/htt_rx.c
浏览文件 @
59e25676
...
...
@@ -271,13 +271,14 @@ void ath10k_htt_rx_free(struct ath10k_htt *htt)
static
inline
struct
sk_buff
*
ath10k_htt_rx_netbuf_pop
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
int
idx
;
struct
sk_buff
*
msdu
;
lockdep_assert_held
(
&
htt
->
rx_ring
.
lock
);
if
(
htt
->
rx_ring
.
fill_cnt
==
0
)
{
ath10k_warn
(
"tried to pop sk_buff from an empty rx ring
\n
"
);
ath10k_warn
(
ar
,
"tried to pop sk_buff from an empty rx ring
\n
"
);
return
NULL
;
}
...
...
@@ -311,6 +312,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
struct
sk_buff
**
tail_msdu
,
u32
*
attention
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
int
msdu_len
,
msdu_chaining
=
0
;
struct
sk_buff
*
msdu
;
struct
htt_rx_desc
*
rx_desc
;
...
...
@@ -318,7 +320,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
lockdep_assert_held
(
&
htt
->
rx_ring
.
lock
);
if
(
htt
->
rx_confused
)
{
ath10k_warn
(
"htt is confused. refusing rx
\n
"
);
ath10k_warn
(
ar
,
"htt is confused. refusing rx
\n
"
);
return
-
1
;
}
...
...
@@ -331,7 +333,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
msdu
->
len
+
skb_tailroom
(
msdu
),
DMA_FROM_DEVICE
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx pop: "
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx pop: "
,
msdu
->
data
,
msdu
->
len
+
skb_tailroom
(
msdu
));
rx_desc
=
(
struct
htt_rx_desc
*
)
msdu
->
data
;
...
...
@@ -354,7 +356,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
ath10k_htt_rx_free_msdu_chain
(
*
head_msdu
);
*
head_msdu
=
NULL
;
msdu
=
NULL
;
ath10k_err
(
"htt rx stopped. cannot recover
\n
"
);
ath10k_err
(
ar
,
"htt rx stopped. cannot recover
\n
"
);
htt
->
rx_confused
=
true
;
break
;
}
...
...
@@ -429,7 +431,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
next
->
len
+
skb_tailroom
(
next
),
DMA_FROM_DEVICE
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx chained: "
,
next
->
data
,
next
->
len
+
skb_tailroom
(
next
));
...
...
@@ -483,13 +485,14 @@ static void ath10k_htt_rx_replenish_task(unsigned long ptr)
int
ath10k_htt_rx_alloc
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
dma_addr_t
paddr
;
void
*
vaddr
;
struct
timer_list
*
timer
=
&
htt
->
rx_ring
.
refill_retry_timer
;
htt
->
rx_ring
.
size
=
ath10k_htt_rx_ring_size
(
htt
);
if
(
!
is_power_of_2
(
htt
->
rx_ring
.
size
))
{
ath10k_warn
(
"htt rx ring size is not power of 2
\n
"
);
ath10k_warn
(
ar
,
"htt rx ring size is not power of 2
\n
"
);
return
-
EINVAL
;
}
...
...
@@ -550,7 +553,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
tasklet_init
(
&
htt
->
txrx_compl_task
,
ath10k_htt_txrx_compl_task
,
(
unsigned
long
)
htt
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"htt rx ring size %d fill_level %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"htt rx ring size %d fill_level %d
\n
"
,
htt
->
rx_ring
.
size
,
htt
->
rx_ring
.
fill_level
);
return
0
;
...
...
@@ -572,7 +575,8 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
return
-
ENOMEM
;
}
static
int
ath10k_htt_rx_crypto_param_len
(
enum
htt_rx_mpdu_encrypt_type
type
)
static
int
ath10k_htt_rx_crypto_param_len
(
struct
ath10k
*
ar
,
enum
htt_rx_mpdu_encrypt_type
type
)
{
switch
(
type
)
{
case
HTT_RX_MPDU_ENCRYPT_WEP40
:
...
...
@@ -588,11 +592,12 @@ static int ath10k_htt_rx_crypto_param_len(enum htt_rx_mpdu_encrypt_type type)
return
0
;
}
ath10k_warn
(
"unknown encryption type %d
\n
"
,
type
);
ath10k_warn
(
ar
,
"unknown encryption type %d
\n
"
,
type
);
return
0
;
}
static
int
ath10k_htt_rx_crypto_tail_len
(
enum
htt_rx_mpdu_encrypt_type
type
)
static
int
ath10k_htt_rx_crypto_tail_len
(
struct
ath10k
*
ar
,
enum
htt_rx_mpdu_encrypt_type
type
)
{
switch
(
type
)
{
case
HTT_RX_MPDU_ENCRYPT_NONE
:
...
...
@@ -608,7 +613,7 @@ static int ath10k_htt_rx_crypto_tail_len(enum htt_rx_mpdu_encrypt_type type)
return
8
;
}
ath10k_warn
(
"unknown encryption type %d
\n
"
,
type
);
ath10k_warn
(
ar
,
"unknown encryption type %d
\n
"
,
type
);
return
0
;
}
...
...
@@ -819,19 +824,55 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
return
true
;
}
static
const
char
*
const
tid_to_ac
[]
=
{
"BE"
,
"BK"
,
"BK"
,
"BE"
,
"VI"
,
"VI"
,
"VO"
,
"VO"
,
};
static
char
*
ath10k_get_tid
(
struct
ieee80211_hdr
*
hdr
,
char
*
out
,
size_t
size
)
{
u8
*
qc
;
int
tid
;
if
(
!
ieee80211_is_data_qos
(
hdr
->
frame_control
))
return
""
;
qc
=
ieee80211_get_qos_ctl
(
hdr
);
tid
=
*
qc
&
IEEE80211_QOS_CTL_TID_MASK
;
if
(
tid
<
8
)
snprintf
(
out
,
size
,
"tid %d (%s)"
,
tid
,
tid_to_ac
[
tid
]);
else
snprintf
(
out
,
size
,
"tid %d"
,
tid
);
return
out
;
}
static
void
ath10k_process_rx
(
struct
ath10k
*
ar
,
struct
ieee80211_rx_status
*
rx_status
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_rx_status
*
status
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
char
tid
[
32
];
status
=
IEEE80211_SKB_RXCB
(
skb
);
*
status
=
*
rx_status
;
ath10k_dbg
(
ATH10K_DBG_DATA
,
"rx skb %p len %u
%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %imic-err
%i
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_DATA
,
"rx skb %p len %u
peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more
%i
\n
"
,
skb
,
skb
->
len
,
ieee80211_get_SA
(
hdr
),
ath10k_get_tid
(
hdr
,
tid
,
sizeof
(
tid
)),
is_multicast_ether_addr
(
ieee80211_get_DA
(
hdr
))
?
"mcast"
:
"ucast"
,
(
__le16_to_cpu
(
hdr
->
seq_ctrl
)
&
IEEE80211_SCTL_SEQ
)
>>
4
,
status
->
flag
==
0
?
"legacy"
:
""
,
status
->
flag
&
RX_FLAG_HT
?
"ht"
:
""
,
status
->
flag
&
RX_FLAG_VHT
?
"vht"
:
""
,
...
...
@@ -843,8 +884,9 @@ static void ath10k_process_rx(struct ath10k *ar,
status
->
freq
,
status
->
band
,
status
->
flag
,
!!
(
status
->
flag
&
RX_FLAG_FAILED_FCS_CRC
),
!!
(
status
->
flag
&
RX_FLAG_MMIC_ERROR
));
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"rx skb: "
,
!!
(
status
->
flag
&
RX_FLAG_MMIC_ERROR
),
!!
(
status
->
flag
&
RX_FLAG_AMSDU_MORE
));
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"rx skb: "
,
skb
->
data
,
skb
->
len
);
ieee80211_rx
(
ar
->
hw
,
skb
);
...
...
@@ -860,13 +902,14 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
struct
ieee80211_rx_status
*
rx_status
,
struct
sk_buff
*
skb_in
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
htt_rx_desc
*
rxd
;
struct
sk_buff
*
skb
=
skb_in
;
struct
sk_buff
*
first
;
enum
rx_msdu_decap_format
fmt
;
enum
htt_rx_mpdu_encrypt_type
enctype
;
struct
ieee80211_hdr
*
hdr
;
u8
hdr_buf
[
64
],
addr
[
ETH_ALEN
],
*
qos
;
u8
hdr_buf
[
64
],
da
[
ETH_ALEN
],
sa
[
ETH_ALEN
],
*
qos
;
unsigned
int
hdr_len
;
rxd
=
(
void
*
)
skb
->
data
-
sizeof
(
*
rxd
);
...
...
@@ -893,8 +936,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
/* First frame in an A-MSDU chain has more decapped data. */
if
(
skb
==
first
)
{
len
=
round_up
(
ieee80211_hdrlen
(
hdr
->
frame_control
),
4
);
len
+=
round_up
(
ath10k_htt_rx_crypto_param_len
(
enctype
)
,
4
);
len
+=
round_up
(
ath10k_htt_rx_crypto_param_len
(
ar
,
enctype
),
4
);
decap_hdr
+=
len
;
}
...
...
@@ -904,10 +947,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
skb_trim
(
skb
,
skb
->
len
-
FCS_LEN
);
break
;
case
RX_MSDU_DECAP_NATIVE_WIFI
:
/* pull decapped header and copy DA */
/* pull decapped header and copy
SA &
DA */
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
hdr_len
=
ath10k_htt_rx_nwifi_hdrlen
(
hdr
);
memcpy
(
addr
,
ieee80211_get_DA
(
hdr
),
ETH_ALEN
);
memcpy
(
da
,
ieee80211_get_DA
(
hdr
),
ETH_ALEN
);
memcpy
(
sa
,
ieee80211_get_SA
(
hdr
),
ETH_ALEN
);
skb_pull
(
skb
,
hdr_len
);
/* push original 802.11 header */
...
...
@@ -921,8 +965,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
qos
=
ieee80211_get_qos_ctl
(
hdr
);
qos
[
0
]
&=
~
IEEE80211_QOS_CTL_A_MSDU_PRESENT
;
/* original 802.11 header has a different DA */
memcpy
(
ieee80211_get_DA
(
hdr
),
addr
,
ETH_ALEN
);
/* original 802.11 header has a different DA and in
* case of 4addr it may also have different SA
*/
memcpy
(
ieee80211_get_DA
(
hdr
),
da
,
ETH_ALEN
);
memcpy
(
ieee80211_get_SA
(
hdr
),
sa
,
ETH_ALEN
);
break
;
case
RX_MSDU_DECAP_ETHERNET2_DIX
:
/* strip ethernet header and insert decapped 802.11
...
...
@@ -965,6 +1012,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
struct
ieee80211_rx_status
*
rx_status
,
struct
sk_buff
*
skb
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
htt_rx_desc
*
rxd
;
struct
ieee80211_hdr
*
hdr
;
enum
rx_msdu_decap_format
fmt
;
...
...
@@ -974,7 +1022,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
/* This shouldn't happen. If it does than it may be a FW bug. */
if
(
skb
->
next
)
{
ath10k_warn
(
"htt rx received chained non A-MSDU frame
\n
"
);
ath10k_warn
(
ar
,
"htt rx received chained non A-MSDU frame
\n
"
);
ath10k_htt_rx_free_msdu_chain
(
skb
->
next
);
skb
->
next
=
NULL
;
}
...
...
@@ -1011,7 +1059,8 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
rfc1042
=
hdr
;
rfc1042
+=
roundup
(
hdr_len
,
4
);
rfc1042
+=
roundup
(
ath10k_htt_rx_crypto_param_len
(
enctype
),
4
);
rfc1042
+=
roundup
(
ath10k_htt_rx_crypto_param_len
(
ar
,
enctype
),
4
);
skb_pull
(
skb
,
sizeof
(
struct
ethhdr
));
memcpy
(
skb_push
(
skb
,
sizeof
(
struct
rfc1042_hdr
)),
...
...
@@ -1120,27 +1169,29 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
bool
channel_set
,
u32
attention
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
if
(
head
->
len
==
0
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx dropping due to zero-len
\n
"
);
return
false
;
}
if
(
attention
&
RX_ATTENTION_FLAGS_DECRYPT_ERR
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx dropping due to decrypt-err
\n
"
);
return
false
;
}
if
(
!
channel_set
)
{
ath10k_warn
(
"no channel configured; ignoring frame!
\n
"
);
ath10k_warn
(
ar
,
"no channel configured; ignoring frame!
\n
"
);
return
false
;
}
/* Skip mgmt frames while we handle this in WMI */
if
(
status
==
HTT_RX_IND_MPDU_STATUS_MGMT_CTRL
||
attention
&
RX_ATTENTION_FLAGS_MGMT_TYPE
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx mgmt ctrl
\n
"
);
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx mgmt ctrl
\n
"
);
return
false
;
}
...
...
@@ -1148,14 +1199,14 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
status
!=
HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR
&&
status
!=
HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER
&&
!
htt
->
ar
->
monitor_started
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx ignoring frame w/ status %d
\n
"
,
status
);
return
false
;
}
if
(
test_bit
(
ATH10K_CAC_RUNNING
,
&
htt
->
ar
->
dev_flags
))
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx CAC running
\n
"
);
return
false
;
}
...
...
@@ -1166,6 +1217,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
static
void
ath10k_htt_rx_handler
(
struct
ath10k_htt
*
htt
,
struct
htt_rx_indication
*
rx
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
ieee80211_rx_status
*
rx_status
=
&
htt
->
rx_status
;
struct
htt_rx_indication_mpdu_range
*
mpdu_ranges
;
struct
htt_rx_desc
*
rxd
;
...
...
@@ -1211,7 +1263,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
rx_status
);
}
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx ind: "
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx ind: "
,
rx
,
sizeof
(
*
rx
)
+
(
sizeof
(
struct
htt_rx_indication_mpdu_range
)
*
num_mpdu_ranges
));
...
...
@@ -1233,7 +1285,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
&
attention
);
if
(
ret
<
0
)
{
ath10k_warn
(
"failed to pop amsdu from htt rx ring %d
\n
"
,
ath10k_warn
(
ar
,
"failed to pop amsdu from htt rx ring %d
\n
"
,
ret
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
continue
;
...
...
@@ -1282,6 +1334,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
static
void
ath10k_htt_rx_frag_handler
(
struct
ath10k_htt
*
htt
,
struct
htt_rx_fragment_indication
*
frag
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
sk_buff
*
msdu_head
,
*
msdu_tail
;
enum
htt_rx_mpdu_encrypt_type
enctype
;
struct
htt_rx_desc
*
rxd
;
...
...
@@ -1308,10 +1361,10 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
&
attention
);
spin_unlock_bh
(
&
htt
->
rx_ring
.
lock
);
ath10k_dbg
(
ATH10K_DBG_HTT_DUMP
,
"htt rx frag ahead
\n
"
);
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT_DUMP
,
"htt rx frag ahead
\n
"
);
if
(
ret
)
{
ath10k_warn
(
"failed to pop amsdu from httr rx ring for fragmented rx %d
\n
"
,
ath10k_warn
(
ar
,
"failed to pop amsdu from httr rx ring for fragmented rx %d
\n
"
,
ret
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
return
;
...
...
@@ -1328,7 +1381,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
RX_MSDU_START_INFO1_DECAP_FORMAT
);
if
(
fmt
!=
RX_MSDU_DECAP_RAW
)
{
ath10k_warn
(
"we dont support non-raw fragmented rx yet
\n
"
);
ath10k_warn
(
ar
,
"we dont support non-raw fragmented rx yet
\n
"
);
dev_kfree_skb_any
(
msdu_head
);
goto
end
;
}
...
...
@@ -1340,17 +1393,17 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
msdu_head
->
ip_summed
=
ath10k_htt_rx_get_csum_state
(
msdu_head
);
if
(
tkip_mic_err
)
ath10k_warn
(
"tkip mic error
\n
"
);
ath10k_warn
(
ar
,
"tkip mic error
\n
"
);
if
(
decrypt_err
)
{
ath10k_warn
(
"decryption err in fragmented rx
\n
"
);
ath10k_warn
(
ar
,
"decryption err in fragmented rx
\n
"
);
dev_kfree_skb_any
(
msdu_head
);
goto
end
;
}
if
(
enctype
!=
HTT_RX_MPDU_ENCRYPT_NONE
)
{
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
paramlen
=
ath10k_htt_rx_crypto_param_len
(
enctype
);
paramlen
=
ath10k_htt_rx_crypto_param_len
(
ar
,
enctype
);
/* It is more efficient to move the header than the payload */
memmove
((
void
*
)
msdu_head
->
data
+
paramlen
,
...
...
@@ -1364,7 +1417,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
trim
=
4
;
/* remove crypto trailer */
trim
+=
ath10k_htt_rx_crypto_tail_len
(
enctype
);
trim
+=
ath10k_htt_rx_crypto_tail_len
(
ar
,
enctype
);
/* last fragment of TKIP frags has MIC */
if
(
!
ieee80211_has_morefrags
(
hdr
->
frame_control
)
&&
...
...
@@ -1372,20 +1425,20 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
trim
+=
8
;
if
(
trim
>
msdu_head
->
len
)
{
ath10k_warn
(
"htt rx fragment: trailer longer than the frame itself? drop
\n
"
);
ath10k_warn
(
ar
,
"htt rx fragment: trailer longer than the frame itself? drop
\n
"
);
dev_kfree_skb_any
(
msdu_head
);
goto
end
;
}
skb_trim
(
msdu_head
,
msdu_head
->
len
-
trim
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx frag mpdu: "
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx frag mpdu: "
,
msdu_head
->
data
,
msdu_head
->
len
);
ath10k_process_rx
(
htt
->
ar
,
rx_status
,
msdu_head
);
end:
if
(
fw_desc_len
>
0
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"expecting more fragmented rx in one indication %d
\n
"
,
fw_desc_len
);
}
...
...
@@ -1415,12 +1468,12 @@ static void ath10k_htt_rx_frm_tx_compl(struct ath10k *ar,
tx_done
.
discard
=
true
;
break
;
default:
ath10k_warn
(
"unhandled tx completion status %d
\n
"
,
status
);
ath10k_warn
(
ar
,
"unhandled tx completion status %d
\n
"
,
status
);
tx_done
.
discard
=
true
;
break
;
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt tx completion num_msdus %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt tx completion num_msdus %d
\n
"
,
resp
->
data_tx_completion
.
num_msdus
);
for
(
i
=
0
;
i
<
resp
->
data_tx_completion
.
num_msdus
;
i
++
)
{
...
...
@@ -1441,14 +1494,14 @@ static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp)
tid
=
MS
(
info0
,
HTT_RX_BA_INFO0_TID
);
peer_id
=
MS
(
info0
,
HTT_RX_BA_INFO0_PEER_ID
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx addba tid %hu peer_id %hu size %hhu
\n
"
,
tid
,
peer_id
,
ev
->
window_size
);
spin_lock_bh
(
&
ar
->
data_lock
);
peer
=
ath10k_peer_find_by_id
(
ar
,
peer_id
);
if
(
!
peer
)
{
ath10k_warn
(
"received addba event for invalid peer_id: %hu
\n
"
,
ath10k_warn
(
ar
,
"received addba event for invalid peer_id: %hu
\n
"
,
peer_id
);
spin_unlock_bh
(
&
ar
->
data_lock
);
return
;
...
...
@@ -1456,13 +1509,13 @@ static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp)
arvif
=
ath10k_get_arvif
(
ar
,
peer
->
vdev_id
);
if
(
!
arvif
)
{
ath10k_warn
(
"received addba event for invalid vdev_id: %u
\n
"
,
ath10k_warn
(
ar
,
"received addba event for invalid vdev_id: %u
\n
"
,
peer
->
vdev_id
);
spin_unlock_bh
(
&
ar
->
data_lock
);
return
;
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx start rx ba session sta %pM tid %hu size %hhu
\n
"
,
peer
->
addr
,
tid
,
ev
->
window_size
);
...
...
@@ -1481,14 +1534,14 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp)
tid
=
MS
(
info0
,
HTT_RX_BA_INFO0_TID
);
peer_id
=
MS
(
info0
,
HTT_RX_BA_INFO0_PEER_ID
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx delba tid %hu peer_id %hu
\n
"
,
tid
,
peer_id
);
spin_lock_bh
(
&
ar
->
data_lock
);
peer
=
ath10k_peer_find_by_id
(
ar
,
peer_id
);
if
(
!
peer
)
{
ath10k_warn
(
"received addba event for invalid peer_id: %hu
\n
"
,
ath10k_warn
(
ar
,
"received addba event for invalid peer_id: %hu
\n
"
,
peer_id
);
spin_unlock_bh
(
&
ar
->
data_lock
);
return
;
...
...
@@ -1496,13 +1549,13 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp)
arvif
=
ath10k_get_arvif
(
ar
,
peer
->
vdev_id
);
if
(
!
arvif
)
{
ath10k_warn
(
"received addba event for invalid vdev_id: %u
\n
"
,
ath10k_warn
(
ar
,
"received addba event for invalid vdev_id: %u
\n
"
,
peer
->
vdev_id
);
spin_unlock_bh
(
&
ar
->
data_lock
);
return
;
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx stop rx ba session sta %pM tid %hu
\n
"
,
peer
->
addr
,
tid
);
...
...
@@ -1517,9 +1570,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
/* confirm alignment */
if
(
!
IS_ALIGNED
((
unsigned
long
)
skb
->
data
,
4
))
ath10k_warn
(
"unaligned htt message, expect trouble
\n
"
);
ath10k_warn
(
ar
,
"unaligned htt message, expect trouble
\n
"
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx, msg_type: 0x%0X
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt rx, msg_type: 0x%0X
\n
"
,
resp
->
hdr
.
msg_type
);
switch
(
resp
->
hdr
.
msg_type
)
{
case
HTT_T2H_MSG_TYPE_VERSION_CONF
:
{
...
...
@@ -1583,7 +1636,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
struct
ath10k
*
ar
=
htt
->
ar
;
struct
htt_security_indication
*
ev
=
&
resp
->
security_indication
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"sec ind peer_id %d unicast %d type %d
\n
"
,
__le16_to_cpu
(
ev
->
peer_id
),
!!
(
ev
->
flags
&
HTT_SECURITY_IS_UNICAST
),
...
...
@@ -1592,7 +1645,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
break
;
}
case
HTT_T2H_MSG_TYPE_RX_FRAG_IND
:
{
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt event: "
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt event: "
,
skb
->
data
,
skb
->
len
);
ath10k_htt_rx_frag_handler
(
htt
,
&
resp
->
rx_frag_ind
);
break
;
...
...
@@ -1609,7 +1662,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
* sends all tx frames as already inspected so this shouldn't
* happen unless fw has a bug.
*/
ath10k_warn
(
"received an unexpected htt tx inspect event
\n
"
);
ath10k_warn
(
ar
,
"received an unexpected htt tx inspect event
\n
"
);
break
;
case
HTT_T2H_MSG_TYPE_RX_ADDBA
:
ath10k_htt_rx_addba
(
ar
,
resp
);
...
...
@@ -1624,9 +1677,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
break
;
}
default:
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt event (%d) not handled
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt event (%d) not handled
\n
"
,
resp
->
hdr
.
msg_type
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt event: "
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt event: "
,
skb
->
data
,
skb
->
len
);
break
;
};
...
...
drivers/net/wireless/ath/ath10k/htt_tx.c
浏览文件 @
59e25676
...
...
@@ -58,6 +58,7 @@ static int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt)
int
ath10k_htt_tx_alloc_msdu_id
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
int
msdu_id
;
lockdep_assert_held
(
&
htt
->
tx_lock
);
...
...
@@ -67,24 +68,29 @@ int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt)
if
(
msdu_id
==
htt
->
max_num_pending_tx
)
return
-
ENOBUFS
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt tx alloc msdu_id %d
\n
"
,
msdu_id
);
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt tx alloc msdu_id %d
\n
"
,
msdu_id
);
__set_bit
(
msdu_id
,
htt
->
used_msdu_ids
);
return
msdu_id
;
}
void
ath10k_htt_tx_free_msdu_id
(
struct
ath10k_htt
*
htt
,
u16
msdu_id
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
lockdep_assert_held
(
&
htt
->
tx_lock
);
if
(
!
test_bit
(
msdu_id
,
htt
->
used_msdu_ids
))
ath10k_warn
(
"trying to free unallocated msdu_id %d
\n
"
,
msdu_id
);
ath10k_warn
(
ar
,
"trying to free unallocated msdu_id %d
\n
"
,
msdu_id
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt tx free msdu_id %hu
\n
"
,
msdu_id
);
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt tx free msdu_id %hu
\n
"
,
msdu_id
);
__clear_bit
(
msdu_id
,
htt
->
used_msdu_ids
);
}
int
ath10k_htt_tx_alloc
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
spin_lock_init
(
&
htt
->
tx_lock
);
init_waitqueue_head
(
&
htt
->
empty_tx_wq
);
...
...
@@ -93,7 +99,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
else
htt
->
max_num_pending_tx
=
TARGET_NUM_MSDU_DESC
;
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"htt tx max num pending tx %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_BOOT
,
"htt tx max num pending tx %d
\n
"
,
htt
->
max_num_pending_tx
);
htt
->
pending_tx
=
kzalloc
(
sizeof
(
*
htt
->
pending_tx
)
*
...
...
@@ -122,6 +128,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
static
void
ath10k_htt_tx_free_pending
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
htt_tx_done
tx_done
=
{
0
};
int
msdu_id
;
...
...
@@ -130,7 +137,7 @@ static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt)
if
(
!
test_bit
(
msdu_id
,
htt
->
used_msdu_ids
))
continue
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
"force cleanup msdu_id %hu
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"force cleanup msdu_id %hu
\n
"
,
msdu_id
);
tx_done
.
discard
=
1
;
...
...
@@ -157,6 +164,7 @@ void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
int
ath10k_htt_h2t_ver_req_msg
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
sk_buff
*
skb
;
struct
htt_cmd
*
cmd
;
int
len
=
0
;
...
...
@@ -165,7 +173,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
len
+=
sizeof
(
cmd
->
hdr
);
len
+=
sizeof
(
cmd
->
ver_req
);
skb
=
ath10k_htc_alloc_skb
(
len
);
skb
=
ath10k_htc_alloc_skb
(
ar
,
len
);
if
(
!
skb
)
return
-
ENOMEM
;
...
...
@@ -184,6 +192,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
int
ath10k_htt_h2t_stats_req
(
struct
ath10k_htt
*
htt
,
u8
mask
,
u64
cookie
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
htt_stats_req
*
req
;
struct
sk_buff
*
skb
;
struct
htt_cmd
*
cmd
;
...
...
@@ -192,7 +201,7 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
len
+=
sizeof
(
cmd
->
hdr
);
len
+=
sizeof
(
cmd
->
stats_req
);
skb
=
ath10k_htc_alloc_skb
(
len
);
skb
=
ath10k_htc_alloc_skb
(
ar
,
len
);
if
(
!
skb
)
return
-
ENOMEM
;
...
...
@@ -214,7 +223,8 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
ret
=
ath10k_htc_send
(
&
htt
->
ar
->
htc
,
htt
->
eid
,
skb
);
if
(
ret
)
{
ath10k_warn
(
"failed to send htt type stats request: %d"
,
ret
);
ath10k_warn
(
ar
,
"failed to send htt type stats request: %d"
,
ret
);
dev_kfree_skb_any
(
skb
);
return
ret
;
}
...
...
@@ -224,6 +234,7 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
int
ath10k_htt_send_rx_ring_cfg_ll
(
struct
ath10k_htt
*
htt
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
sk_buff
*
skb
;
struct
htt_cmd
*
cmd
;
struct
htt_rx_ring_setup_ring
*
ring
;
...
...
@@ -242,7 +253,7 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
len
=
sizeof
(
cmd
->
hdr
)
+
sizeof
(
cmd
->
rx_setup
.
hdr
)
+
(
sizeof
(
*
ring
)
*
num_rx_ring
);
skb
=
ath10k_htc_alloc_skb
(
len
);
skb
=
ath10k_htc_alloc_skb
(
ar
,
len
);
if
(
!
skb
)
return
-
ENOMEM
;
...
...
@@ -311,6 +322,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
u8
max_subfrms_ampdu
,
u8
max_subfrms_amsdu
)
{
struct
ath10k
*
ar
=
htt
->
ar
;
struct
htt_aggr_conf
*
aggr_conf
;
struct
sk_buff
*
skb
;
struct
htt_cmd
*
cmd
;
...
...
@@ -328,7 +340,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
len
=
sizeof
(
cmd
->
hdr
);
len
+=
sizeof
(
cmd
->
aggr_conf
);
skb
=
ath10k_htc_alloc_skb
(
len
);
skb
=
ath10k_htc_alloc_skb
(
ar
,
len
);
if
(
!
skb
)
return
-
ENOMEM
;
...
...
@@ -340,7 +352,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
aggr_conf
->
max_num_ampdu_subframes
=
max_subfrms_ampdu
;
aggr_conf
->
max_num_amsdu_subframes
=
max_subfrms_amsdu
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt h2t aggr cfg msg amsdu %d ampdu %d"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt h2t aggr cfg msg amsdu %d ampdu %d"
,
aggr_conf
->
max_num_amsdu_subframes
,
aggr_conf
->
max_num_ampdu_subframes
);
...
...
@@ -355,7 +367,8 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
int
ath10k_htt_mgmt_tx
(
struct
ath10k_htt
*
htt
,
struct
sk_buff
*
msdu
)
{
struct
device
*
dev
=
htt
->
ar
->
dev
;
struct
ath10k
*
ar
=
htt
->
ar
;
struct
device
*
dev
=
ar
->
dev
;
struct
sk_buff
*
txdesc
=
NULL
;
struct
htt_cmd
*
cmd
;
struct
ath10k_skb_cb
*
skb_cb
=
ATH10K_SKB_CB
(
msdu
);
...
...
@@ -382,7 +395,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
htt
->
pending_tx
[
msdu_id
]
=
msdu
;
spin_unlock_bh
(
&
htt
->
tx_lock
);
txdesc
=
ath10k_htc_alloc_skb
(
len
);
txdesc
=
ath10k_htc_alloc_skb
(
ar
,
len
);
if
(
!
txdesc
)
{
res
=
-
ENOMEM
;
goto
err_free_msdu_id
;
...
...
@@ -429,7 +442,8 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
int
ath10k_htt_tx
(
struct
ath10k_htt
*
htt
,
struct
sk_buff
*
msdu
)
{
struct
device
*
dev
=
htt
->
ar
->
dev
;
struct
ath10k
*
ar
=
htt
->
ar
;
struct
device
*
dev
=
ar
->
dev
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
msdu
->
data
;
struct
ath10k_skb_cb
*
skb_cb
=
ATH10K_SKB_CB
(
msdu
);
struct
ath10k_hif_sg_item
sg_items
[
2
];
...
...
@@ -545,11 +559,11 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
frags_paddr
=
__cpu_to_le32
(
frags_paddr
);
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
peerid
=
__cpu_to_le32
(
HTT_INVALID_PEERID
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu
\n
"
,
flags0
,
flags1
,
msdu
->
len
,
msdu_id
,
frags_paddr
,
(
u32
)
skb_cb
->
paddr
,
vdev_id
,
tid
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt tx msdu: "
,
ath10k_dbg_dump
(
ar
,
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt tx msdu: "
,
msdu
->
data
,
msdu
->
len
);
sg_items
[
0
].
transfer_id
=
0
;
...
...
drivers/net/wireless/ath/ath10k/hw.h
浏览文件 @
59e25676
...
...
@@ -28,16 +28,19 @@
#define QCA988X_HW_2_0_CHIP_ID_REV 0x2
#define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0"
#define QCA988X_HW_2_0_FW_FILE "firmware.bin"
#define QCA988X_HW_2_0_FW_
2_FILE "firmware-2
.bin"
#define QCA988X_HW_2_0_FW_
3_FILE "firmware-3
.bin"
#define QCA988X_HW_2_0_OTP_FILE "otp.bin"
#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234
#define ATH10K_FW_API2_FILE "firmware-2.bin"
#define ATH10K_FW_API3_FILE "firmware-3.bin"
/* includes also the null byte */
#define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K"
#define REG_DUMP_COUNT_QCA988X 60
struct
ath10k_fw_ie
{
__le32
id
;
__le32
len
;
...
...
drivers/net/wireless/ath/ath10k/mac.c
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath10k/mac.h
浏览文件 @
59e25676
...
...
@@ -26,12 +26,14 @@ struct ath10k_generic_iter {
int
ret
;
};
struct
ath10k
*
ath10k_mac_create
(
void
);
struct
ath10k
*
ath10k_mac_create
(
size_t
priv_size
);
void
ath10k_mac_destroy
(
struct
ath10k
*
ar
);
int
ath10k_mac_register
(
struct
ath10k
*
ar
);
void
ath10k_mac_unregister
(
struct
ath10k
*
ar
);
struct
ath10k_vif
*
ath10k_get_arvif
(
struct
ath10k
*
ar
,
u32
vdev_id
);
void
ath10k_reset_scan
(
unsigned
long
ptr
);
void
__ath10k_scan_finish
(
struct
ath10k
*
ar
);
void
ath10k_scan_finish
(
struct
ath10k
*
ar
);
void
ath10k_scan_timeout_work
(
struct
work_struct
*
work
);
void
ath10k_offchan_tx_purge
(
struct
ath10k
*
ar
);
void
ath10k_offchan_tx_work
(
struct
work_struct
*
work
);
void
ath10k_mgmt_over_wmi_tx_purge
(
struct
ath10k
*
ar
);
...
...
drivers/net/wireless/ath/ath10k/pci.c
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath10k/pci.h
浏览文件 @
59e25676
...
...
@@ -23,9 +23,6 @@
#include "hw.h"
#include "ce.h"
/* FW dump area */
#define REG_DUMP_COUNT_QCA988X 60
/*
* maximum number of bytes that can be handled atomically by DiagRead/DiagWrite
*/
...
...
@@ -103,12 +100,12 @@ struct pcie_state {
* NOTE: Structure is shared between Host software and Target firmware!
*/
struct
ce_pipe_config
{
u
32
pipenum
;
u
32
pipedir
;
u
32
nentries
;
u
32
nbytes_max
;
u
32
flags
;
u
32
reserved
;
__le
32
pipenum
;
__le
32
pipedir
;
__le
32
nentries
;
__le
32
nbytes_max
;
__le
32
flags
;
__le
32
reserved
;
};
/*
...
...
@@ -130,17 +127,9 @@ struct ce_pipe_config {
/* Establish a mapping between a service/direction and a pipe. */
struct
service_to_pipe
{
u32
service_id
;
u32
pipedir
;
u32
pipenum
;
};
enum
ath10k_pci_features
{
ATH10K_PCI_FEATURE_MSI_X
=
0
,
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
=
1
,
/* keep last */
ATH10K_PCI_FEATURE_COUNT
__le32
service_id
;
__le32
pipedir
;
__le32
pipenum
;
};
/* Per-pipe state. */
...
...
@@ -169,8 +158,6 @@ struct ath10k_pci {
struct
ath10k
*
ar
;
void
__iomem
*
mem
;
DECLARE_BITMAP
(
features
,
ATH10K_PCI_FEATURE_COUNT
);
/*
* Number of MSI interrupts granted, 0 --> using legacy PCI line
* interrupts.
...
...
@@ -179,12 +166,6 @@ struct ath10k_pci {
struct
tasklet_struct
intr_tq
;
struct
tasklet_struct
msi_fw_err
;
struct
tasklet_struct
early_irq_tasklet
;
int
started
;
atomic_t
keep_awake_count
;
bool
verified_awake
;
struct
ath10k_pci_pipe
pipe_info
[
CE_COUNT_MAX
];
...
...
@@ -198,27 +179,15 @@ struct ath10k_pci {
/* Map CE id to ce_state */
struct
ath10k_ce_pipe
ce_states
[
CE_COUNT_MAX
];
struct
timer_list
rx_post_retry
;
};
static
inline
struct
ath10k_pci
*
ath10k_pci_priv
(
struct
ath10k
*
ar
)
{
return
ar
->
hif
.
priv
;
}
static
inline
u32
ath10k_pci_reg_read32
(
struct
ath10k
*
ar
,
u32
addr
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
return
ioread32
(
ar_pci
->
mem
+
PCIE_LOCAL_BASE_ADDRESS
+
addr
);
}
static
inline
void
ath10k_pci_reg_write32
(
struct
ath10k
*
ar
,
u32
addr
,
u32
val
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
iowrite32
(
val
,
ar_pci
->
mem
+
PCIE_LOCAL_BASE_ADDRESS
+
addr
);
return
(
struct
ath10k_pci
*
)
ar
->
drv_priv
;
}
#define ATH10K_PCI_RX_POST_RETRY_MS 50
#define ATH_PCI_RESET_WAIT_MAX 10
/* ms */
#define PCIE_WAKE_TIMEOUT 5000
/* 5ms */
...
...
@@ -242,35 +211,17 @@ static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val)
/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
#define DIAG_ACCESS_CE_TIMEOUT_MS 10
/*
* This API allows the Host to access Target registers directly
* and relatively efficiently over PCIe.
* This allows the Host to avoid extra overhead associated with
* sending a message to firmware and waiting for a response message
* from firmware, as is done on other interconnects.
*
* Yet there is some complexity with direct accesses because the
* Target's power state is not known a priori. The Host must issue
* special PCIe reads/writes in order to explicitly wake the Target
* and to verify that it is awake and will remain awake.
*
* Usage:
/* Target exposes its registers for direct access. However before host can
* access them it needs to make sure the target is awake (ath10k_pci_wake,
* ath10k_pci_wake_wait, ath10k_pci_is_awake). Once target is awake it won't go
* to sleep unless host tells it to (ath10k_pci_sleep).
*
* Use ath10k_pci_read32 and ath10k_pci_write32 to access Target space.
* These calls must be bracketed by ath10k_pci_wake and
* ath10k_pci_sleep. A single BEGIN/END pair is adequate for
* multiple READ/WRITE operations.
* If host tries to access target registers without waking it up it can
* scribble over host memory.
*
* Use ath10k_pci_wake to put the Target in a state in
* which it is legal for the Host to directly access it. This
* may involve waking the Target from a low power state, which
* may take up to 2Ms!
*
* Use ath10k_pci_sleep to tell the Target that as far as
* this code path is concerned, it no longer needs to remain
* directly accessible. BEGIN/END is under a reference counter;
* multiple code paths may issue BEGIN/END on a single targid.
* If target is asleep waking it up may take up to even 2ms.
*/
static
inline
void
ath10k_pci_write32
(
struct
ath10k
*
ar
,
u32
offset
,
u32
value
)
{
...
...
@@ -296,25 +247,18 @@ static inline void ath10k_pci_soc_write32(struct ath10k *ar, u32 addr, u32 val)
ath10k_pci_write32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
addr
,
val
);
}
int
ath10k_do_pci_wake
(
struct
ath10k
*
ar
);
void
ath10k_do_pci_sleep
(
struct
ath10k
*
ar
);
static
inline
int
ath10k_pci_wake
(
struct
ath10k
*
ar
)
static
inline
u32
ath10k_pci_reg_read32
(
struct
ath10k
*
ar
,
u32
addr
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
if
(
test_bit
(
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
,
ar_pci
->
features
))
return
ath10k_do_pci_wake
(
ar
);
return
0
;
return
ioread32
(
ar_pci
->
mem
+
PCIE_LOCAL_BASE_ADDRESS
+
addr
);
}
static
inline
void
ath10k_pci_
sleep
(
struct
ath10k
*
ar
)
static
inline
void
ath10k_pci_
reg_write32
(
struct
ath10k
*
ar
,
u32
addr
,
u32
val
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
if
(
test_bit
(
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
,
ar_pci
->
features
))
ath10k_do_pci_sleep
(
ar
);
iowrite32
(
val
,
ar_pci
->
mem
+
PCIE_LOCAL_BASE_ADDRESS
+
addr
);
}
#endif
/* _PCI_H_ */
drivers/net/wireless/ath/ath10k/spectral.c
0 → 100644
浏览文件 @
59e25676
/*
* Copyright (c) 2013 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/relay.h>
#include "core.h"
#include "debug.h"
static
void
send_fft_sample
(
struct
ath10k
*
ar
,
const
struct
fft_sample_tlv
*
fft_sample_tlv
)
{
int
length
;
if
(
!
ar
->
spectral
.
rfs_chan_spec_scan
)
return
;
length
=
__be16_to_cpu
(
fft_sample_tlv
->
length
)
+
sizeof
(
*
fft_sample_tlv
);
relay_write
(
ar
->
spectral
.
rfs_chan_spec_scan
,
fft_sample_tlv
,
length
);
}
static
uint8_t
get_max_exp
(
s8
max_index
,
u16
max_magnitude
,
size_t
bin_len
,
u8
*
data
)
{
int
dc_pos
;
u8
max_exp
;
dc_pos
=
bin_len
/
2
;
/* peak index outside of bins */
if
(
dc_pos
<
max_index
||
-
dc_pos
>=
max_index
)
return
0
;
for
(
max_exp
=
0
;
max_exp
<
8
;
max_exp
++
)
{
if
(
data
[
dc_pos
+
max_index
]
==
(
max_magnitude
>>
max_exp
))
break
;
}
/* max_exp not found */
if
(
data
[
dc_pos
+
max_index
]
!=
(
max_magnitude
>>
max_exp
))
return
0
;
return
max_exp
;
}
int
ath10k_spectral_process_fft
(
struct
ath10k
*
ar
,
struct
wmi_single_phyerr_rx_event
*
event
,
struct
phyerr_fft_report
*
fftr
,
size_t
bin_len
,
u64
tsf
)
{
struct
fft_sample_ath10k
*
fft_sample
;
u8
buf
[
sizeof
(
*
fft_sample
)
+
SPECTRAL_ATH10K_MAX_NUM_BINS
];
u16
freq1
,
freq2
,
total_gain_db
,
base_pwr_db
,
length
,
peak_mag
;
u32
reg0
,
reg1
,
nf_list1
,
nf_list2
;
u8
chain_idx
,
*
bins
;
int
dc_pos
;
fft_sample
=
(
struct
fft_sample_ath10k
*
)
&
buf
;
if
(
bin_len
<
64
||
bin_len
>
SPECTRAL_ATH10K_MAX_NUM_BINS
)
return
-
EINVAL
;
reg0
=
__le32_to_cpu
(
fftr
->
reg0
);
reg1
=
__le32_to_cpu
(
fftr
->
reg1
);
length
=
sizeof
(
*
fft_sample
)
-
sizeof
(
struct
fft_sample_tlv
)
+
bin_len
;
fft_sample
->
tlv
.
type
=
ATH_FFT_SAMPLE_ATH10K
;
fft_sample
->
tlv
.
length
=
__cpu_to_be16
(
length
);
/* TODO: there might be a reason why the hardware reports 20/40/80 MHz,
* but the results/plots suggest that its actually 22/44/88 MHz.
*/
switch
(
event
->
hdr
.
chan_width_mhz
)
{
case
20
:
fft_sample
->
chan_width_mhz
=
22
;
break
;
case
40
:
fft_sample
->
chan_width_mhz
=
44
;
break
;
case
80
:
/* TODO: As experiments with an analogue sender and various
* configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz)
* show, the particular configuration of 80 MHz/64 bins does
* not match with the other smaples at all. Until the reason
* for that is found, don't report these samples.
*/
if
(
bin_len
==
64
)
return
-
EINVAL
;
fft_sample
->
chan_width_mhz
=
88
;
break
;
default:
fft_sample
->
chan_width_mhz
=
event
->
hdr
.
chan_width_mhz
;
}
fft_sample
->
relpwr_db
=
MS
(
reg1
,
SEARCH_FFT_REPORT_REG1_RELPWR_DB
);
fft_sample
->
avgpwr_db
=
MS
(
reg1
,
SEARCH_FFT_REPORT_REG1_AVGPWR_DB
);
peak_mag
=
MS
(
reg1
,
SEARCH_FFT_REPORT_REG1_PEAK_MAG
);
fft_sample
->
max_magnitude
=
__cpu_to_be16
(
peak_mag
);
fft_sample
->
max_index
=
MS
(
reg0
,
SEARCH_FFT_REPORT_REG0_PEAK_SIDX
);
fft_sample
->
rssi
=
event
->
hdr
.
rssi_combined
;
total_gain_db
=
MS
(
reg0
,
SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB
);
base_pwr_db
=
MS
(
reg0
,
SEARCH_FFT_REPORT_REG0_BASE_PWR_DB
);
fft_sample
->
total_gain_db
=
__cpu_to_be16
(
total_gain_db
);
fft_sample
->
base_pwr_db
=
__cpu_to_be16
(
base_pwr_db
);
freq1
=
__le16_to_cpu
(
event
->
hdr
.
freq1
);
freq2
=
__le16_to_cpu
(
event
->
hdr
.
freq2
);
fft_sample
->
freq1
=
__cpu_to_be16
(
freq1
);
fft_sample
->
freq2
=
__cpu_to_be16
(
freq2
);
nf_list1
=
__le32_to_cpu
(
event
->
hdr
.
nf_list_1
);
nf_list2
=
__le32_to_cpu
(
event
->
hdr
.
nf_list_2
);
chain_idx
=
MS
(
reg0
,
SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX
);
switch
(
chain_idx
)
{
case
0
:
fft_sample
->
noise
=
__cpu_to_be16
(
nf_list1
&
0xffffu
);
break
;
case
1
:
fft_sample
->
noise
=
__cpu_to_be16
((
nf_list1
>>
16
)
&
0xffffu
);
break
;
case
2
:
fft_sample
->
noise
=
__cpu_to_be16
(
nf_list2
&
0xffffu
);
break
;
case
3
:
fft_sample
->
noise
=
__cpu_to_be16
((
nf_list2
>>
16
)
&
0xffffu
);
break
;
}
bins
=
(
u8
*
)
fftr
;
bins
+=
sizeof
(
*
fftr
);
fft_sample
->
tsf
=
__cpu_to_be64
(
tsf
);
/* max_exp has been directly reported by previous hardware (ath9k),
* maybe its possible to get it by other means?
*/
fft_sample
->
max_exp
=
get_max_exp
(
fft_sample
->
max_index
,
peak_mag
,
bin_len
,
bins
);
memcpy
(
fft_sample
->
data
,
bins
,
bin_len
);
/* DC value (value in the middle) is the blind spot of the spectral
* sample and invalid, interpolate it.
*/
dc_pos
=
bin_len
/
2
;
fft_sample
->
data
[
dc_pos
]
=
(
fft_sample
->
data
[
dc_pos
+
1
]
+
fft_sample
->
data
[
dc_pos
-
1
])
/
2
;
send_fft_sample
(
ar
,
&
fft_sample
->
tlv
);
return
0
;
}
static
struct
ath10k_vif
*
ath10k_get_spectral_vdev
(
struct
ath10k
*
ar
)
{
struct
ath10k_vif
*
arvif
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
if
(
list_empty
(
&
ar
->
arvifs
))
return
NULL
;
/* if there already is a vif doing spectral, return that. */
list_for_each_entry
(
arvif
,
&
ar
->
arvifs
,
list
)
if
(
arvif
->
spectral_enabled
)
return
arvif
;
/* otherwise, return the first vif. */
return
list_first_entry
(
&
ar
->
arvifs
,
typeof
(
*
arvif
),
list
);
}
static
int
ath10k_spectral_scan_trigger
(
struct
ath10k
*
ar
)
{
struct
ath10k_vif
*
arvif
;
int
res
;
int
vdev_id
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
arvif
=
ath10k_get_spectral_vdev
(
ar
);
if
(
!
arvif
)
return
-
ENODEV
;
vdev_id
=
arvif
->
vdev_id
;
if
(
ar
->
spectral
.
mode
==
SPECTRAL_DISABLED
)
return
0
;
res
=
ath10k_wmi_vdev_spectral_enable
(
ar
,
vdev_id
,
WMI_SPECTRAL_TRIGGER_CMD_CLEAR
,
WMI_SPECTRAL_ENABLE_CMD_ENABLE
);
if
(
res
<
0
)
return
res
;
res
=
ath10k_wmi_vdev_spectral_enable
(
ar
,
vdev_id
,
WMI_SPECTRAL_TRIGGER_CMD_TRIGGER
,
WMI_SPECTRAL_ENABLE_CMD_ENABLE
);
if
(
res
<
0
)
return
res
;
return
0
;
}
static
int
ath10k_spectral_scan_config
(
struct
ath10k
*
ar
,
enum
ath10k_spectral_mode
mode
)
{
struct
wmi_vdev_spectral_conf_arg
arg
;
struct
ath10k_vif
*
arvif
;
int
vdev_id
,
count
,
res
=
0
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
arvif
=
ath10k_get_spectral_vdev
(
ar
);
if
(
!
arvif
)
return
-
ENODEV
;
vdev_id
=
arvif
->
vdev_id
;
arvif
->
spectral_enabled
=
(
mode
!=
SPECTRAL_DISABLED
);
ar
->
spectral
.
mode
=
mode
;
res
=
ath10k_wmi_vdev_spectral_enable
(
ar
,
vdev_id
,
WMI_SPECTRAL_TRIGGER_CMD_CLEAR
,
WMI_SPECTRAL_ENABLE_CMD_DISABLE
);
if
(
res
<
0
)
{
ath10k_warn
(
ar
,
"failed to enable spectral scan: %d
\n
"
,
res
);
return
res
;
}
if
(
mode
==
SPECTRAL_DISABLED
)
return
0
;
if
(
mode
==
SPECTRAL_BACKGROUND
)
count
=
WMI_SPECTRAL_COUNT_DEFAULT
;
else
count
=
max_t
(
u8
,
1
,
ar
->
spectral
.
config
.
count
);
arg
.
vdev_id
=
vdev_id
;
arg
.
scan_count
=
count
;
arg
.
scan_period
=
WMI_SPECTRAL_PERIOD_DEFAULT
;
arg
.
scan_priority
=
WMI_SPECTRAL_PRIORITY_DEFAULT
;
arg
.
scan_fft_size
=
ar
->
spectral
.
config
.
fft_size
;
arg
.
scan_gc_ena
=
WMI_SPECTRAL_GC_ENA_DEFAULT
;
arg
.
scan_restart_ena
=
WMI_SPECTRAL_RESTART_ENA_DEFAULT
;
arg
.
scan_noise_floor_ref
=
WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT
;
arg
.
scan_init_delay
=
WMI_SPECTRAL_INIT_DELAY_DEFAULT
;
arg
.
scan_nb_tone_thr
=
WMI_SPECTRAL_NB_TONE_THR_DEFAULT
;
arg
.
scan_str_bin_thr
=
WMI_SPECTRAL_STR_BIN_THR_DEFAULT
;
arg
.
scan_wb_rpt_mode
=
WMI_SPECTRAL_WB_RPT_MODE_DEFAULT
;
arg
.
scan_rssi_rpt_mode
=
WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT
;
arg
.
scan_rssi_thr
=
WMI_SPECTRAL_RSSI_THR_DEFAULT
;
arg
.
scan_pwr_format
=
WMI_SPECTRAL_PWR_FORMAT_DEFAULT
;
arg
.
scan_rpt_mode
=
WMI_SPECTRAL_RPT_MODE_DEFAULT
;
arg
.
scan_bin_scale
=
WMI_SPECTRAL_BIN_SCALE_DEFAULT
;
arg
.
scan_dbm_adj
=
WMI_SPECTRAL_DBM_ADJ_DEFAULT
;
arg
.
scan_chn_mask
=
WMI_SPECTRAL_CHN_MASK_DEFAULT
;
res
=
ath10k_wmi_vdev_spectral_conf
(
ar
,
&
arg
);
if
(
res
<
0
)
{
ath10k_warn
(
ar
,
"failed to configure spectral scan: %d
\n
"
,
res
);
return
res
;
}
return
0
;
}
static
ssize_t
read_file_spec_scan_ctl
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
char
*
mode
=
""
;
unsigned
int
len
;
enum
ath10k_spectral_mode
spectral_mode
;
mutex_lock
(
&
ar
->
conf_mutex
);
spectral_mode
=
ar
->
spectral
.
mode
;
mutex_unlock
(
&
ar
->
conf_mutex
);
switch
(
spectral_mode
)
{
case
SPECTRAL_DISABLED
:
mode
=
"disable"
;
break
;
case
SPECTRAL_BACKGROUND
:
mode
=
"background"
;
break
;
case
SPECTRAL_MANUAL
:
mode
=
"manual"
;
break
;
}
len
=
strlen
(
mode
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
mode
,
len
);
}
static
ssize_t
write_file_spec_scan_ctl
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
char
buf
[
32
];
ssize_t
len
;
int
res
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
mutex_lock
(
&
ar
->
conf_mutex
);
if
(
strncmp
(
"trigger"
,
buf
,
7
)
==
0
)
{
if
(
ar
->
spectral
.
mode
==
SPECTRAL_MANUAL
||
ar
->
spectral
.
mode
==
SPECTRAL_BACKGROUND
)
{
/* reset the configuration to adopt possibly changed
* debugfs parameters
*/
res
=
ath10k_spectral_scan_config
(
ar
,
ar
->
spectral
.
mode
);
if
(
res
<
0
)
{
ath10k_warn
(
ar
,
"failed to reconfigure spectral scan: %d
\n
"
,
res
);
}
res
=
ath10k_spectral_scan_trigger
(
ar
);
if
(
res
<
0
)
{
ath10k_warn
(
ar
,
"failed to trigger spectral scan: %d
\n
"
,
res
);
}
}
else
{
res
=
-
EINVAL
;
}
}
else
if
(
strncmp
(
"background"
,
buf
,
9
)
==
0
)
{
res
=
ath10k_spectral_scan_config
(
ar
,
SPECTRAL_BACKGROUND
);
}
else
if
(
strncmp
(
"manual"
,
buf
,
6
)
==
0
)
{
res
=
ath10k_spectral_scan_config
(
ar
,
SPECTRAL_MANUAL
);
}
else
if
(
strncmp
(
"disable"
,
buf
,
7
)
==
0
)
{
res
=
ath10k_spectral_scan_config
(
ar
,
SPECTRAL_DISABLED
);
}
else
{
res
=
-
EINVAL
;
}
mutex_unlock
(
&
ar
->
conf_mutex
);
if
(
res
<
0
)
return
res
;
return
count
;
}
static
const
struct
file_operations
fops_spec_scan_ctl
=
{
.
read
=
read_file_spec_scan_ctl
,
.
write
=
write_file_spec_scan_ctl
,
.
open
=
simple_open
,
.
owner
=
THIS_MODULE
,
.
llseek
=
default_llseek
,
};
static
ssize_t
read_file_spectral_count
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
char
buf
[
32
];
unsigned
int
len
;
u8
spectral_count
;
mutex_lock
(
&
ar
->
conf_mutex
);
spectral_count
=
ar
->
spectral
.
config
.
count
;
mutex_unlock
(
&
ar
->
conf_mutex
);
len
=
sprintf
(
buf
,
"%d
\n
"
,
spectral_count
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
len
);
}
static
ssize_t
write_file_spectral_count
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
unsigned
long
val
;
char
buf
[
32
];
ssize_t
len
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
if
(
kstrtoul
(
buf
,
0
,
&
val
))
return
-
EINVAL
;
if
(
val
<
0
||
val
>
255
)
return
-
EINVAL
;
mutex_lock
(
&
ar
->
conf_mutex
);
ar
->
spectral
.
config
.
count
=
val
;
mutex_unlock
(
&
ar
->
conf_mutex
);
return
count
;
}
static
const
struct
file_operations
fops_spectral_count
=
{
.
read
=
read_file_spectral_count
,
.
write
=
write_file_spectral_count
,
.
open
=
simple_open
,
.
owner
=
THIS_MODULE
,
.
llseek
=
default_llseek
,
};
static
ssize_t
read_file_spectral_bins
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
char
buf
[
32
];
unsigned
int
len
,
bins
,
fft_size
,
bin_scale
;
mutex_lock
(
&
ar
->
conf_mutex
);
fft_size
=
ar
->
spectral
.
config
.
fft_size
;
bin_scale
=
WMI_SPECTRAL_BIN_SCALE_DEFAULT
;
bins
=
1
<<
(
fft_size
-
bin_scale
);
mutex_unlock
(
&
ar
->
conf_mutex
);
len
=
sprintf
(
buf
,
"%d
\n
"
,
bins
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
len
);
}
static
ssize_t
write_file_spectral_bins
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
unsigned
long
val
;
char
buf
[
32
];
ssize_t
len
;
len
=
min
(
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
len
))
return
-
EFAULT
;
buf
[
len
]
=
'\0'
;
if
(
kstrtoul
(
buf
,
0
,
&
val
))
return
-
EINVAL
;
if
(
val
<
64
||
val
>
SPECTRAL_ATH10K_MAX_NUM_BINS
)
return
-
EINVAL
;
if
(
!
is_power_of_2
(
val
))
return
-
EINVAL
;
mutex_lock
(
&
ar
->
conf_mutex
);
ar
->
spectral
.
config
.
fft_size
=
ilog2
(
val
);
ar
->
spectral
.
config
.
fft_size
+=
WMI_SPECTRAL_BIN_SCALE_DEFAULT
;
mutex_unlock
(
&
ar
->
conf_mutex
);
return
count
;
}
static
const
struct
file_operations
fops_spectral_bins
=
{
.
read
=
read_file_spectral_bins
,
.
write
=
write_file_spectral_bins
,
.
open
=
simple_open
,
.
owner
=
THIS_MODULE
,
.
llseek
=
default_llseek
,
};
static
struct
dentry
*
create_buf_file_handler
(
const
char
*
filename
,
struct
dentry
*
parent
,
umode_t
mode
,
struct
rchan_buf
*
buf
,
int
*
is_global
)
{
struct
dentry
*
buf_file
;
buf_file
=
debugfs_create_file
(
filename
,
mode
,
parent
,
buf
,
&
relay_file_operations
);
*
is_global
=
1
;
return
buf_file
;
}
static
int
remove_buf_file_handler
(
struct
dentry
*
dentry
)
{
debugfs_remove
(
dentry
);
return
0
;
}
static
struct
rchan_callbacks
rfs_spec_scan_cb
=
{
.
create_buf_file
=
create_buf_file_handler
,
.
remove_buf_file
=
remove_buf_file_handler
,
};
int
ath10k_spectral_start
(
struct
ath10k
*
ar
)
{
struct
ath10k_vif
*
arvif
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
list_for_each_entry
(
arvif
,
&
ar
->
arvifs
,
list
)
arvif
->
spectral_enabled
=
0
;
ar
->
spectral
.
mode
=
SPECTRAL_DISABLED
;
ar
->
spectral
.
config
.
count
=
WMI_SPECTRAL_COUNT_DEFAULT
;
ar
->
spectral
.
config
.
fft_size
=
WMI_SPECTRAL_FFT_SIZE_DEFAULT
;
return
0
;
}
int
ath10k_spectral_vif_stop
(
struct
ath10k_vif
*
arvif
)
{
if
(
!
arvif
->
spectral_enabled
)
return
0
;
return
ath10k_spectral_scan_config
(
arvif
->
ar
,
SPECTRAL_DISABLED
);
}
int
ath10k_spectral_create
(
struct
ath10k
*
ar
)
{
ar
->
spectral
.
rfs_chan_spec_scan
=
relay_open
(
"spectral_scan"
,
ar
->
debug
.
debugfs_phy
,
1024
,
256
,
&
rfs_spec_scan_cb
,
NULL
);
debugfs_create_file
(
"spectral_scan_ctl"
,
S_IRUSR
|
S_IWUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_spec_scan_ctl
);
debugfs_create_file
(
"spectral_count"
,
S_IRUSR
|
S_IWUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_spectral_count
);
debugfs_create_file
(
"spectral_bins"
,
S_IRUSR
|
S_IWUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_spectral_bins
);
return
0
;
}
void
ath10k_spectral_destroy
(
struct
ath10k
*
ar
)
{
if
(
ar
->
spectral
.
rfs_chan_spec_scan
)
{
relay_close
(
ar
->
spectral
.
rfs_chan_spec_scan
);
ar
->
spectral
.
rfs_chan_spec_scan
=
NULL
;
}
}
drivers/net/wireless/ath/ath10k/spectral.h
0 → 100644
浏览文件 @
59e25676
/*
* Copyright (c) 2013 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef SPECTRAL_H
#define SPECTRAL_H
#include "../spectral_common.h"
/**
* struct ath10k_spec_scan - parameters for Atheros spectral scan
*
* @count: number of scan results requested for manual mode
* @fft_size: number of bins to be requested = 2^(fft_size - bin_scale)
*/
struct
ath10k_spec_scan
{
u8
count
;
u8
fft_size
;
};
/* enum ath10k_spectral_mode:
*
* @SPECTRAL_DISABLED: spectral mode is disabled
* @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with
* something else.
* @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples
* is performed manually.
*/
enum
ath10k_spectral_mode
{
SPECTRAL_DISABLED
=
0
,
SPECTRAL_BACKGROUND
,
SPECTRAL_MANUAL
,
};
#ifdef CONFIG_ATH10K_DEBUGFS
int
ath10k_spectral_process_fft
(
struct
ath10k
*
ar
,
struct
wmi_single_phyerr_rx_event
*
event
,
struct
phyerr_fft_report
*
fftr
,
size_t
bin_len
,
u64
tsf
);
int
ath10k_spectral_start
(
struct
ath10k
*
ar
);
int
ath10k_spectral_vif_stop
(
struct
ath10k_vif
*
arvif
);
int
ath10k_spectral_create
(
struct
ath10k
*
ar
);
void
ath10k_spectral_destroy
(
struct
ath10k
*
ar
);
#else
static
inline
int
ath10k_spectral_process_fft
(
struct
ath10k
*
ar
,
struct
wmi_single_phyerr_rx_event
*
event
,
struct
phyerr_fft_report
*
fftr
,
size_t
bin_len
,
u64
tsf
)
{
return
0
;
}
static
inline
int
ath10k_spectral_start
(
struct
ath10k
*
ar
)
{
return
0
;
}
static
inline
int
ath10k_spectral_vif_stop
(
struct
ath10k_vif
*
arvif
)
{
return
0
;
}
static
inline
int
ath10k_spectral_create
(
struct
ath10k
*
ar
)
{
return
0
;
}
static
inline
void
ath10k_spectral_destroy
(
struct
ath10k
*
ar
)
{
}
#endif
/* CONFIG_ATH10K_DEBUGFS */
#endif
/* SPECTRAL_H */
drivers/net/wireless/ath/ath10k/txrx.c
浏览文件 @
59e25676
...
...
@@ -32,14 +32,14 @@ static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
* offchan_tx_skb. */
spin_lock_bh
(
&
ar
->
data_lock
);
if
(
ar
->
offchan_tx_skb
!=
skb
)
{
ath10k_warn
(
"completed old offchannel frame
\n
"
);
ath10k_warn
(
ar
,
"completed old offchannel frame
\n
"
);
goto
out
;
}
complete
(
&
ar
->
offchan_tx_completed
);
ar
->
offchan_tx_skb
=
NULL
;
/* just for sanity */
ath10k_dbg
(
ATH10K_DBG_HTT
,
"completed offchannel skb %p
\n
"
,
skb
);
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"completed offchannel skb %p
\n
"
,
skb
);
out:
spin_unlock_bh
(
&
ar
->
data_lock
);
}
...
...
@@ -47,18 +47,19 @@ static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
void
ath10k_txrx_tx_unref
(
struct
ath10k_htt
*
htt
,
const
struct
htt_tx_done
*
tx_done
)
{
struct
device
*
dev
=
htt
->
ar
->
dev
;
struct
ath10k
*
ar
=
htt
->
ar
;
struct
device
*
dev
=
ar
->
dev
;
struct
ieee80211_tx_info
*
info
;
struct
ath10k_skb_cb
*
skb_cb
;
struct
sk_buff
*
msdu
;
lockdep_assert_held
(
&
htt
->
tx_lock
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt tx completion msdu_id %u discard %d no_ack %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt tx completion msdu_id %u discard %d no_ack %d
\n
"
,
tx_done
->
msdu_id
,
!!
tx_done
->
discard
,
!!
tx_done
->
no_ack
);
if
(
tx_done
->
msdu_id
>=
htt
->
max_num_pending_tx
)
{
ath10k_warn
(
"warning: msdu_id %d too big, ignoring
\n
"
,
ath10k_warn
(
ar
,
"warning: msdu_id %d too big, ignoring
\n
"
,
tx_done
->
msdu_id
);
return
;
}
...
...
@@ -182,7 +183,7 @@ void ath10k_peer_map_event(struct ath10k_htt *htt,
wake_up
(
&
ar
->
peer_mapping_wq
);
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt peer map vdev %d peer %pM id %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt peer map vdev %d peer %pM id %d
\n
"
,
ev
->
vdev_id
,
ev
->
addr
,
ev
->
peer_id
);
set_bit
(
ev
->
peer_id
,
peer
->
peer_ids
);
...
...
@@ -199,12 +200,12 @@ void ath10k_peer_unmap_event(struct ath10k_htt *htt,
spin_lock_bh
(
&
ar
->
data_lock
);
peer
=
ath10k_peer_find_by_id
(
ar
,
ev
->
peer_id
);
if
(
!
peer
)
{
ath10k_warn
(
"peer-unmap-event: unknown peer id %d
\n
"
,
ath10k_warn
(
ar
,
"peer-unmap-event: unknown peer id %d
\n
"
,
ev
->
peer_id
);
goto
exit
;
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt peer unmap vdev %d peer %pM id %d
\n
"
,
ath10k_dbg
(
ar
,
ATH10K_DBG_HTT
,
"htt peer unmap vdev %d peer %pM id %d
\n
"
,
peer
->
vdev_id
,
peer
->
addr
,
ev
->
peer_id
);
clear_bit
(
ev
->
peer_id
,
peer
->
peer_ids
);
...
...
drivers/net/wireless/ath/ath10k/wmi.c
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath10k/wmi.h
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath6kl/init.c
浏览文件 @
59e25676
...
...
@@ -1049,7 +1049,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
ar
->
hw
.
reserved_ram_size
=
le32_to_cpup
(
val
);
ath6kl_dbg
(
ATH6KL_DBG_BOOT
,
"found reserved ram size ie
0x
%d
\n
"
,
"found reserved ram size ie %d
\n
"
,
ar
->
hw
.
reserved_ram_size
);
break
;
case
ATH6KL_FW_IE_CAPABILITIES
:
...
...
drivers/net/wireless/ath/ath6kl/main.c
浏览文件 @
59e25676
...
...
@@ -225,7 +225,7 @@ int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)
ret
=
ath6kl_hif_diag_write32
(
ar
,
address
,
value
);
if
(
ret
)
{
ath6kl_err
(
"failed to write 0x%x during diagnose window to 0x%
d
\n
"
,
ath6kl_err
(
"failed to write 0x%x during diagnose window to 0x%
x
\n
"
,
address
,
value
);
return
ret
;
}
...
...
drivers/net/wireless/ath/ath6kl/sdio.c
浏览文件 @
59e25676
...
...
@@ -1400,6 +1400,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = {
{
SDIO_DEVICE
(
MANUFACTURER_CODE
,
(
MANUFACTURER_ID_AR6003_BASE
|
0x1
))},
{
SDIO_DEVICE
(
MANUFACTURER_CODE
,
(
MANUFACTURER_ID_AR6004_BASE
|
0x0
))},
{
SDIO_DEVICE
(
MANUFACTURER_CODE
,
(
MANUFACTURER_ID_AR6004_BASE
|
0x1
))},
{
SDIO_DEVICE
(
MANUFACTURER_CODE
,
(
MANUFACTURER_ID_AR6004_BASE
|
0x2
))},
{},
};
...
...
drivers/net/wireless/ath/ath6kl/usb.c
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/ath9k/spectral.h
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
drivers/net/wireless/ath/spectral_common.h
0 → 100644
浏览文件 @
59e25676
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录