Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
98497bb2
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
98497bb2
编写于
9月 26, 2013
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-linville' of
git://github.com/kvalo/ath
上级
b75ff5e8
763b8cd3
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
626 addition
and
428 deletion
+626
-428
drivers/net/wireless/ath/ath10k/ce.c
drivers/net/wireless/ath/ath10k/ce.c
+148
-143
drivers/net/wireless/ath/ath10k/ce.h
drivers/net/wireless/ath/ath10k/ce.h
+29
-45
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.c
+34
-12
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/core.h
+12
-1
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/debug.c
+22
-1
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/htc.c
+4
-4
drivers/net/wireless/ath/ath10k/htt.c
drivers/net/wireless/ath/ath10k/htt.c
+7
-12
drivers/net/wireless/ath/ath10k/htt.h
drivers/net/wireless/ath/ath10k/htt.h
+3
-3
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/htt_rx.c
+10
-2
drivers/net/wireless/ath/ath10k/htt_tx.c
drivers/net/wireless/ath/ath10k/htt_tx.c
+52
-22
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/hw.h
+11
-8
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/mac.c
+12
-10
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.c
+214
-111
drivers/net/wireless/ath/ath10k/pci.h
drivers/net/wireless/ath/ath10k/pci.h
+30
-43
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.c
+25
-8
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/ath/ath10k/wmi.h
+13
-3
未找到文件。
drivers/net/wireless/ath/ath10k/ce.c
浏览文件 @
98497bb2
...
...
@@ -76,36 +76,7 @@ static inline void ath10k_ce_src_ring_write_index_set(struct ath10k *ar,
u32
ce_ctrl_addr
,
unsigned
int
n
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
void
__iomem
*
indicator_addr
;
if
(
!
test_bit
(
ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND
,
ar_pci
->
features
))
{
ath10k_pci_write32
(
ar
,
ce_ctrl_addr
+
SR_WR_INDEX_ADDRESS
,
n
);
return
;
}
/* workaround for QCA988x_1.0 HW CE */
indicator_addr
=
ar_pci
->
mem
+
ce_ctrl_addr
+
DST_WATERMARK_ADDRESS
;
if
(
ce_ctrl_addr
==
ath10k_ce_base_address
(
CDC_WAR_DATA_CE
))
{
iowrite32
((
CDC_WAR_MAGIC_STR
|
n
),
indicator_addr
);
}
else
{
unsigned
long
irq_flags
;
local_irq_save
(
irq_flags
);
iowrite32
(
1
,
indicator_addr
);
/*
* PCIE write waits for ACK in IPQ8K, there is no
* need to read back value.
*/
(
void
)
ioread32
(
indicator_addr
);
(
void
)
ioread32
(
indicator_addr
);
/* conservative */
ath10k_pci_write32
(
ar
,
ce_ctrl_addr
+
SR_WR_INDEX_ADDRESS
,
n
);
iowrite32
(
0
,
indicator_addr
);
local_irq_restore
(
irq_flags
);
}
ath10k_pci_write32
(
ar
,
ce_ctrl_addr
+
SR_WR_INDEX_ADDRESS
,
n
);
}
static
inline
u32
ath10k_ce_src_ring_write_index_get
(
struct
ath10k
*
ar
,
...
...
@@ -285,7 +256,7 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
* ath10k_ce_sendlist_send.
* The caller takes responsibility for any needed locking.
*/
static
int
ath10k_ce_send_nolock
(
struct
ce_stat
e
*
ce_state
,
static
int
ath10k_ce_send_nolock
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
...
...
@@ -293,7 +264,7 @@ static int ath10k_ce_send_nolock(struct ce_state *ce_state,
unsigned
int
flags
)
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ce_ring_state
*
src_ring
=
ce_state
->
src_ring
;
struct
ath10k_ce_ring
*
src_ring
=
ce_state
->
src_ring
;
struct
ce_desc
*
desc
,
*
sdesc
;
unsigned
int
nentries_mask
=
src_ring
->
nentries_mask
;
unsigned
int
sw_index
=
src_ring
->
sw_index
;
...
...
@@ -306,7 +277,9 @@ static int ath10k_ce_send_nolock(struct ce_state *ce_state,
ath10k_warn
(
"%s: send more we can (nbytes: %d, max: %d)
\n
"
,
__func__
,
nbytes
,
ce_state
->
src_sz_max
);
ath10k_pci_wake
(
ar
);
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
ret
;
if
(
unlikely
(
CE_RING_DELTA
(
nentries_mask
,
write_index
,
sw_index
-
1
)
<=
0
))
{
...
...
@@ -346,7 +319,7 @@ static int ath10k_ce_send_nolock(struct ce_state *ce_state,
return
ret
;
}
int
ath10k_ce_send
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_send
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
...
...
@@ -378,12 +351,12 @@ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer,
sendlist
->
num_items
++
;
}
int
ath10k_ce_sendlist_send
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_sendlist_send
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_context
,
struct
ce_sendlist
*
sendlist
,
unsigned
int
transfer_id
)
{
struct
ce_ring_state
*
src_ring
=
ce_state
->
src_ring
;
struct
ath10k_ce_ring
*
src_ring
=
ce_state
->
src_ring
;
struct
ce_sendlist_item
*
item
;
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
...
...
@@ -431,11 +404,11 @@ int ath10k_ce_sendlist_send(struct ce_state *ce_state,
return
ret
;
}
int
ath10k_ce_recv_buf_enqueue
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_recv_buf_enqueue
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_recv_context
,
u32
buffer
)
{
struct
ce_ring_state
*
dest_ring
=
ce_state
->
dest_ring
;
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_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
...
...
@@ -448,7 +421,9 @@ int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state,
write_index
=
dest_ring
->
write_index
;
sw_index
=
dest_ring
->
sw_index
;
ath10k_pci_wake
(
ar
);
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
goto
out
;
if
(
CE_RING_DELTA
(
nentries_mask
,
write_index
,
sw_index
-
1
)
>
0
)
{
struct
ce_desc
*
base
=
dest_ring
->
base_addr_owner_space
;
...
...
@@ -470,6 +445,8 @@ int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state,
ret
=
-
EIO
;
}
ath10k_pci_sleep
(
ar
);
out:
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
return
ret
;
...
...
@@ -479,14 +456,14 @@ int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state,
* Guts of ath10k_ce_completed_recv_next.
* The caller takes responsibility for any necessary locking.
*/
static
int
ath10k_ce_completed_recv_next_nolock
(
struct
ce_stat
e
*
ce_state
,
static
int
ath10k_ce_completed_recv_next_nolock
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
unsigned
int
*
transfer_idp
,
unsigned
int
*
flagsp
)
{
struct
ce_ring_state
*
dest_ring
=
ce_state
->
dest_ring
;
struct
ath10k_ce_ring
*
dest_ring
=
ce_state
->
dest_ring
;
unsigned
int
nentries_mask
=
dest_ring
->
nentries_mask
;
unsigned
int
sw_index
=
dest_ring
->
sw_index
;
...
...
@@ -535,7 +512,7 @@ static int ath10k_ce_completed_recv_next_nolock(struct ce_state *ce_state,
return
0
;
}
int
ath10k_ce_completed_recv_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_completed_recv_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
...
...
@@ -556,11 +533,11 @@ int ath10k_ce_completed_recv_next(struct ce_state *ce_state,
return
ret
;
}
int
ath10k_ce_revoke_recv_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_revoke_recv_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
)
{
struct
ce_ring_state
*
dest_ring
;
struct
ath10k_ce_ring
*
dest_ring
;
unsigned
int
nentries_mask
;
unsigned
int
sw_index
;
unsigned
int
write_index
;
...
...
@@ -612,19 +589,20 @@ int ath10k_ce_revoke_recv_next(struct ce_state *ce_state,
* Guts of ath10k_ce_completed_send_next.
* The caller takes responsibility for any necessary locking.
*/
static
int
ath10k_ce_completed_send_next_nolock
(
struct
ce_stat
e
*
ce_state
,
static
int
ath10k_ce_completed_send_next_nolock
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
unsigned
int
*
transfer_idp
)
{
struct
ce_ring_state
*
src_ring
=
ce_state
->
src_ring
;
struct
ath10k_ce_ring
*
src_ring
=
ce_state
->
src_ring
;
u32
ctrl_addr
=
ce_state
->
ctrl_addr
;
struct
ath10k
*
ar
=
ce_state
->
ar
;
unsigned
int
nentries_mask
=
src_ring
->
nentries_mask
;
unsigned
int
sw_index
=
src_ring
->
sw_index
;
struct
ce_desc
*
sdesc
,
*
sbase
;
unsigned
int
read_index
;
int
ret
=
-
EIO
;
int
ret
;
if
(
src_ring
->
hw_index
==
sw_index
)
{
/*
...
...
@@ -634,48 +612,54 @@ static int ath10k_ce_completed_send_next_nolock(struct ce_state *ce_state,
* the SW has really caught up to the HW, or if the cached
* value of the HW index has become stale.
*/
ath10k_pci_wake
(
ar
);
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
ret
;
src_ring
->
hw_index
=
ath10k_ce_src_ring_read_index_get
(
ar
,
ctrl_addr
);
src_ring
->
hw_index
&=
nentries_mask
;
ath10k_pci_sleep
(
ar
);
}
read_index
=
src_ring
->
hw_index
;
if
((
read_index
!=
sw_index
)
&&
(
read_index
!=
0xffffffff
))
{
struct
ce_desc
*
sbase
=
src_ring
->
shadow_base
;
struct
ce_desc
*
sdesc
=
CE_SRC_RING_TO_DESC
(
sbase
,
sw_index
);
if
((
read_index
==
sw_index
)
||
(
read_index
==
0xffffffff
))
return
-
EIO
;
/* Return data from completed source descriptor */
*
bufferp
=
__le32_to_cpu
(
sdesc
->
addr
);
*
nbytesp
=
__le16_to_cpu
(
sdesc
->
nbytes
);
*
transfer_idp
=
MS
(
__le16_to_cpu
(
sdesc
->
flags
),
CE_DESC_FLAGS_META_DATA
);
sbase
=
src_ring
->
shadow_base
;
sdesc
=
CE_SRC_RING_TO_DESC
(
sbase
,
sw_index
);
if
(
per_transfer_contextp
)
*
per_transfer_contextp
=
src_ring
->
per_transfer_context
[
sw_index
];
/* Return data from completed source descriptor */
*
bufferp
=
__le32_to_cpu
(
sdesc
->
addr
);
*
nbytesp
=
__le16_to_cpu
(
sdesc
->
nbytes
);
*
transfer_idp
=
MS
(
__le16_to_cpu
(
sdesc
->
flags
),
CE_DESC_FLAGS_META_DATA
);
/* sanity */
src_ring
->
per_transfer_context
[
sw_index
]
=
NULL
;
if
(
per_transfer_contextp
)
*
per_transfer_contextp
=
src_ring
->
per_transfer_context
[
sw_index
];
/* Update sw_index */
sw_index
=
CE_RING_IDX_INCR
(
nentries_mask
,
sw_index
);
src_ring
->
sw_index
=
sw_index
;
ret
=
0
;
}
/* sanity */
src_ring
->
per_transfer_context
[
sw_index
]
=
NULL
;
return
ret
;
/* Update sw_index */
sw_index
=
CE_RING_IDX_INCR
(
nentries_mask
,
sw_index
);
src_ring
->
sw_index
=
sw_index
;
return
0
;
}
/* NB: Modeled after ath10k_ce_completed_send_next */
int
ath10k_ce_cancel_send_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_cancel_send_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
unsigned
int
*
transfer_idp
)
{
struct
ce_ring_state
*
src_ring
;
struct
ath10k_ce_ring
*
src_ring
;
unsigned
int
nentries_mask
;
unsigned
int
sw_index
;
unsigned
int
write_index
;
...
...
@@ -727,7 +711,7 @@ int ath10k_ce_cancel_send_next(struct ce_state *ce_state,
return
ret
;
}
int
ath10k_ce_completed_send_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_completed_send_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
...
...
@@ -756,15 +740,19 @@ int ath10k_ce_completed_send_next(struct ce_state *ce_state,
void
ath10k_ce_per_engine_service
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ce_state
*
ce_state
=
ar_pci
->
ce_id_to_state
[
ce_id
];
struct
ath10k_ce_pipe
*
ce_state
=
&
ar_pci
->
ce_states
[
ce_id
];
u32
ctrl_addr
=
ce_state
->
ctrl_addr
;
void
*
transfer_context
;
u32
buf
;
unsigned
int
nbytes
;
unsigned
int
id
;
unsigned
int
flags
;
int
ret
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
ath10k_pci_wake
(
ar
);
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
/* Clear the copy-complete interrupts that will be handled here. */
...
...
@@ -823,10 +811,13 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
void
ath10k_ce_per_engine_service_any
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
int
ce_id
;
int
ce_id
,
ret
;
u32
intr_summary
;
ath10k_pci_wake
(
ar
);
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
intr_summary
=
CE_INTERRUPT_SUMMARY
(
ar
);
for
(
ce_id
=
0
;
intr_summary
&&
(
ce_id
<
ar_pci
->
ce_count
);
ce_id
++
)
{
...
...
@@ -849,13 +840,16 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
*
* Called with ce_lock held.
*/
static
void
ath10k_ce_per_engine_handler_adjust
(
struct
ce_stat
e
*
ce_state
,
static
void
ath10k_ce_per_engine_handler_adjust
(
struct
ath10k_ce_pip
e
*
ce_state
,
int
disable_copy_compl_intr
)
{
u32
ctrl_addr
=
ce_state
->
ctrl_addr
;
struct
ath10k
*
ar
=
ce_state
->
ar
;
int
ret
;
ath10k_pci_wake
(
ar
);
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
if
((
!
disable_copy_compl_intr
)
&&
(
ce_state
->
send_cb
||
ce_state
->
recv_cb
))
...
...
@@ -871,11 +865,14 @@ static void ath10k_ce_per_engine_handler_adjust(struct ce_state *ce_state,
void
ath10k_ce_disable_interrupts
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
int
ce_id
;
int
ce_id
,
ret
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
;
ath10k_pci_wake
(
ar
);
for
(
ce_id
=
0
;
ce_id
<
ar_pci
->
ce_count
;
ce_id
++
)
{
struct
ce_state
*
ce_state
=
ar_pci
->
ce_id_to_state
[
ce_id
];
struct
ath10k_ce_pipe
*
ce_state
=
&
ar_pci
->
ce_states
[
ce_id
];
u32
ctrl_addr
=
ce_state
->
ctrl_addr
;
ath10k_ce_copy_complete_intr_disable
(
ar
,
ctrl_addr
);
...
...
@@ -883,12 +880,12 @@ void ath10k_ce_disable_interrupts(struct ath10k *ar)
ath10k_pci_sleep
(
ar
);
}
void
ath10k_ce_send_cb_register
(
struct
ce_stat
e
*
ce_state
,
void
(
*
send_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
),
void
ath10k_ce_send_cb_register
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
(
*
send_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
),
int
disable_interrupts
)
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
...
...
@@ -900,13 +897,13 @@ void ath10k_ce_send_cb_register(struct ce_state *ce_state,
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
}
void
ath10k_ce_recv_cb_register
(
struct
ce_stat
e
*
ce_state
,
void
(
*
recv_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
))
void
ath10k_ce_recv_cb_register
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
(
*
recv_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
))
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
...
...
@@ -919,11 +916,11 @@ void ath10k_ce_recv_cb_register(struct ce_state *ce_state,
static
int
ath10k_ce_init_src_ring
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
struct
ce_stat
e
*
ce_state
,
struct
ath10k_ce_pip
e
*
ce_state
,
const
struct
ce_attr
*
attr
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ce_ring_state
*
src_ring
;
struct
ath10k_ce_ring
*
src_ring
;
unsigned
int
nentries
=
attr
->
src_nentries
;
unsigned
int
ce_nbytes
;
u32
ctrl_addr
=
ath10k_ce_base_address
(
ce_id
);
...
...
@@ -937,19 +934,18 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
return
0
;
}
ce_nbytes
=
sizeof
(
struct
ce_ring_state
)
+
(
nentries
*
sizeof
(
void
*
));
ce_nbytes
=
sizeof
(
struct
ath10k_ce_ring
)
+
(
nentries
*
sizeof
(
void
*
));
ptr
=
kzalloc
(
ce_nbytes
,
GFP_KERNEL
);
if
(
ptr
==
NULL
)
return
-
ENOMEM
;
ce_state
->
src_ring
=
(
struct
ce_ring_state
*
)
ptr
;
ce_state
->
src_ring
=
(
struct
ath10k_ce_ring
*
)
ptr
;
src_ring
=
ce_state
->
src_ring
;
ptr
+=
sizeof
(
struct
ce_ring_state
);
ptr
+=
sizeof
(
struct
ath10k_ce_ring
);
src_ring
->
nentries
=
nentries
;
src_ring
->
nentries_mask
=
nentries
-
1
;
ath10k_pci_wake
(
ar
);
src_ring
->
sw_index
=
ath10k_ce_src_ring_read_index_get
(
ar
,
ctrl_addr
);
src_ring
->
sw_index
&=
src_ring
->
nentries_mask
;
src_ring
->
hw_index
=
src_ring
->
sw_index
;
...
...
@@ -957,7 +953,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
src_ring
->
write_index
=
ath10k_ce_src_ring_write_index_get
(
ar
,
ctrl_addr
);
src_ring
->
write_index
&=
src_ring
->
nentries_mask
;
ath10k_pci_sleep
(
ar
);
src_ring
->
per_transfer_context
=
(
void
**
)
ptr
;
...
...
@@ -970,6 +965,12 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
(
nentries
*
sizeof
(
struct
ce_desc
)
+
CE_DESC_RING_ALIGN
),
&
base_addr
);
if
(
!
src_ring
->
base_addr_owner_space_unaligned
)
{
kfree
(
ce_state
->
src_ring
);
ce_state
->
src_ring
=
NULL
;
return
-
ENOMEM
;
}
src_ring
->
base_addr_ce_space_unaligned
=
base_addr
;
src_ring
->
base_addr_owner_space
=
PTR_ALIGN
(
...
...
@@ -986,12 +987,21 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
src_ring
->
shadow_base_unaligned
=
kmalloc
((
nentries
*
sizeof
(
struct
ce_desc
)
+
CE_DESC_RING_ALIGN
),
GFP_KERNEL
);
if
(
!
src_ring
->
shadow_base_unaligned
)
{
pci_free_consistent
(
ar_pci
->
pdev
,
(
nentries
*
sizeof
(
struct
ce_desc
)
+
CE_DESC_RING_ALIGN
),
src_ring
->
base_addr_owner_space
,
src_ring
->
base_addr_ce_space
);
kfree
(
ce_state
->
src_ring
);
ce_state
->
src_ring
=
NULL
;
return
-
ENOMEM
;
}
src_ring
->
shadow_base
=
PTR_ALIGN
(
src_ring
->
shadow_base_unaligned
,
CE_DESC_RING_ALIGN
);
ath10k_pci_wake
(
ar
);
ath10k_ce_src_ring_base_addr_set
(
ar
,
ctrl_addr
,
src_ring
->
base_addr_ce_space
);
ath10k_ce_src_ring_size_set
(
ar
,
ctrl_addr
,
nentries
);
...
...
@@ -999,18 +1009,17 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
ath10k_ce_src_ring_byte_swap_set
(
ar
,
ctrl_addr
,
0
);
ath10k_ce_src_ring_lowmark_set
(
ar
,
ctrl_addr
,
0
);
ath10k_ce_src_ring_highmark_set
(
ar
,
ctrl_addr
,
nentries
);
ath10k_pci_sleep
(
ar
);
return
0
;
}
static
int
ath10k_ce_init_dest_ring
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
struct
ce_stat
e
*
ce_state
,
struct
ath10k_ce_pip
e
*
ce_state
,
const
struct
ce_attr
*
attr
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ce_ring_state
*
dest_ring
;
struct
ath10k_ce_ring
*
dest_ring
;
unsigned
int
nentries
=
attr
->
dest_nentries
;
unsigned
int
ce_nbytes
;
u32
ctrl_addr
=
ath10k_ce_base_address
(
ce_id
);
...
...
@@ -1024,25 +1033,23 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
return
0
;
}
ce_nbytes
=
sizeof
(
struct
ce_ring_state
)
+
(
nentries
*
sizeof
(
void
*
));
ce_nbytes
=
sizeof
(
struct
ath10k_ce_ring
)
+
(
nentries
*
sizeof
(
void
*
));
ptr
=
kzalloc
(
ce_nbytes
,
GFP_KERNEL
);
if
(
ptr
==
NULL
)
return
-
ENOMEM
;
ce_state
->
dest_ring
=
(
struct
ce_ring_state
*
)
ptr
;
ce_state
->
dest_ring
=
(
struct
ath10k_ce_ring
*
)
ptr
;
dest_ring
=
ce_state
->
dest_ring
;
ptr
+=
sizeof
(
struct
ce_ring_state
);
ptr
+=
sizeof
(
struct
ath10k_ce_ring
);
dest_ring
->
nentries
=
nentries
;
dest_ring
->
nentries_mask
=
nentries
-
1
;
ath10k_pci_wake
(
ar
);
dest_ring
->
sw_index
=
ath10k_ce_dest_ring_read_index_get
(
ar
,
ctrl_addr
);
dest_ring
->
sw_index
&=
dest_ring
->
nentries_mask
;
dest_ring
->
write_index
=
ath10k_ce_dest_ring_write_index_get
(
ar
,
ctrl_addr
);
dest_ring
->
write_index
&=
dest_ring
->
nentries_mask
;
ath10k_pci_sleep
(
ar
);
dest_ring
->
per_transfer_context
=
(
void
**
)
ptr
;
...
...
@@ -1055,6 +1062,12 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
(
nentries
*
sizeof
(
struct
ce_desc
)
+
CE_DESC_RING_ALIGN
),
&
base_addr
);
if
(
!
dest_ring
->
base_addr_owner_space_unaligned
)
{
kfree
(
ce_state
->
dest_ring
);
ce_state
->
dest_ring
=
NULL
;
return
-
ENOMEM
;
}
dest_ring
->
base_addr_ce_space_unaligned
=
base_addr
;
/*
...
...
@@ -1071,44 +1084,31 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
dest_ring
->
base_addr_ce_space_unaligned
,
CE_DESC_RING_ALIGN
);
ath10k_pci_wake
(
ar
);
ath10k_ce_dest_ring_base_addr_set
(
ar
,
ctrl_addr
,
dest_ring
->
base_addr_ce_space
);
ath10k_ce_dest_ring_size_set
(
ar
,
ctrl_addr
,
nentries
);
ath10k_ce_dest_ring_byte_swap_set
(
ar
,
ctrl_addr
,
0
);
ath10k_ce_dest_ring_lowmark_set
(
ar
,
ctrl_addr
,
0
);
ath10k_ce_dest_ring_highmark_set
(
ar
,
ctrl_addr
,
nentries
);
ath10k_pci_sleep
(
ar
);
return
0
;
}
static
struct
ce_stat
e
*
ath10k_ce_init_state
(
struct
ath10k
*
ar
,
static
struct
ath10k_ce_pip
e
*
ath10k_ce_init_state
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
const
struct
ce_attr
*
attr
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ce_state
*
ce_state
=
NULL
;
struct
ath10k_ce_pipe
*
ce_state
=
&
ar_pci
->
ce_states
[
ce_id
]
;
u32
ctrl_addr
=
ath10k_ce_base_address
(
ce_id
);
spin_lock_bh
(
&
ar_pci
->
ce_lock
);
if
(
!
ar_pci
->
ce_id_to_state
[
ce_id
])
{
ce_state
=
kzalloc
(
sizeof
(
*
ce_state
),
GFP_ATOMIC
);
if
(
ce_state
==
NULL
)
{
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
return
NULL
;
}
ar_pci
->
ce_id_to_state
[
ce_id
]
=
ce_state
;
ce_state
->
ar
=
ar
;
ce_state
->
id
=
ce_id
;
ce_state
->
ctrl_addr
=
ctrl_addr
;
ce_state
->
state
=
CE_RUNNING
;
/* Save attribute flags */
ce_state
->
attr_flags
=
attr
->
flags
;
ce_state
->
src_sz_max
=
attr
->
src_sz_max
;
}
ce_state
->
ar
=
ar
;
ce_state
->
id
=
ce_id
;
ce_state
->
ctrl_addr
=
ctrl_addr
;
ce_state
->
attr_flags
=
attr
->
flags
;
ce_state
->
src_sz_max
=
attr
->
src_sz_max
;
spin_unlock_bh
(
&
ar_pci
->
ce_lock
);
...
...
@@ -1122,12 +1122,17 @@ static struct ce_state *ath10k_ce_init_state(struct ath10k *ar,
* initialization. It may be that only one side or the other is
* initialized by software/firmware.
*/
struct
ce_stat
e
*
ath10k_ce_init
(
struct
ath10k
*
ar
,
struct
ath10k_ce_pip
e
*
ath10k_ce_init
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
const
struct
ce_attr
*
attr
)
{
struct
ce_stat
e
*
ce_state
;
struct
ath10k_ce_pip
e
*
ce_state
;
u32
ctrl_addr
=
ath10k_ce_base_address
(
ce_id
);
int
ret
;
ret
=
ath10k_pci_wake
(
ar
);
if
(
ret
)
return
NULL
;
ce_state
=
ath10k_ce_init_state
(
ar
,
ce_id
,
attr
);
if
(
!
ce_state
)
{
...
...
@@ -1136,40 +1141,38 @@ struct ce_state *ath10k_ce_init(struct ath10k *ar,
}
if
(
attr
->
src_nentries
)
{
if
(
ath10k_ce_init_src_ring
(
ar
,
ce_id
,
ce_state
,
attr
))
{
ath10k_err
(
"Failed to initialize CE src ring for ID: %d
\n
"
,
ce_id
);
ret
=
ath10k_ce_init_src_ring
(
ar
,
ce_id
,
ce_state
,
attr
);
if
(
ret
)
{
ath10k_err
(
"Failed to initialize CE src ring for ID: %d (%d)
\n
"
,
ce_id
,
ret
);
ath10k_ce_deinit
(
ce_state
);
return
NULL
;
}
}
if
(
attr
->
dest_nentries
)
{
if
(
ath10k_ce_init_dest_ring
(
ar
,
ce_id
,
ce_state
,
attr
))
{
ath10k_err
(
"Failed to initialize CE dest ring for ID: %d
\n
"
,
ce_id
);
ret
=
ath10k_ce_init_dest_ring
(
ar
,
ce_id
,
ce_state
,
attr
);
if
(
ret
)
{
ath10k_err
(
"Failed to initialize CE dest ring for ID: %d (%d)
\n
"
,
ce_id
,
ret
);
ath10k_ce_deinit
(
ce_state
);
return
NULL
;
}
}
/* Enable CE error interrupts */
ath10k_pci_wake
(
ar
);
ath10k_ce_error_intr_enable
(
ar
,
ctrl_addr
);
ath10k_pci_sleep
(
ar
);
return
ce_state
;
}
void
ath10k_ce_deinit
(
struct
ce_stat
e
*
ce_state
)
void
ath10k_ce_deinit
(
struct
ath10k_ce_pip
e
*
ce_state
)
{
unsigned
int
ce_id
=
ce_state
->
id
;
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
ce_state
->
state
=
CE_UNUSED
;
ar_pci
->
ce_id_to_state
[
ce_id
]
=
NULL
;
if
(
ce_state
->
src_ring
)
{
kfree
(
ce_state
->
src_ring
->
shadow_base_unaligned
);
pci_free_consistent
(
ar_pci
->
pdev
,
...
...
@@ -1190,5 +1193,7 @@ void ath10k_ce_deinit(struct ce_state *ce_state)
ce_state
->
dest_ring
->
base_addr_ce_space
);
kfree
(
ce_state
->
dest_ring
);
}
kfree
(
ce_state
);
ce_state
->
src_ring
=
NULL
;
ce_state
->
dest_ring
=
NULL
;
}
drivers/net/wireless/ath/ath10k/ce.h
浏览文件 @
98497bb2
...
...
@@ -36,16 +36,9 @@
* how to use copy engines.
*/
struct
ce_stat
e
;
struct
ath10k_ce_pip
e
;
/* Copy Engine operational state */
enum
ce_op_state
{
CE_UNUSED
,
CE_PAUSED
,
CE_RUNNING
,
};
#define CE_DESC_FLAGS_GATHER (1 << 0)
#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1)
#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
...
...
@@ -57,8 +50,7 @@ struct ce_desc {
__le16
flags
;
/* %CE_DESC_FLAGS_ */
};
/* Copy Engine Ring internal state */
struct
ce_ring_state
{
struct
ath10k_ce_ring
{
/* Number of entries in this ring; must be power of 2 */
unsigned
int
nentries
;
unsigned
int
nentries_mask
;
...
...
@@ -116,22 +108,20 @@ struct ce_ring_state {
void
**
per_transfer_context
;
};
/* Copy Engine internal state */
struct
ce_state
{
struct
ath10k_ce_pipe
{
struct
ath10k
*
ar
;
unsigned
int
id
;
unsigned
int
attr_flags
;
u32
ctrl_addr
;
enum
ce_op_state
state
;
void
(
*
send_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
(
*
send_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_send_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
);
void
(
*
recv_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
(
*
recv_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_recv_context
,
u32
buffer
,
unsigned
int
nbytes
,
...
...
@@ -139,8 +129,8 @@ struct ce_state {
unsigned
int
flags
);
unsigned
int
src_sz_max
;
struct
ce_ring_state
*
src_ring
;
struct
ce_ring_state
*
dest_ring
;
struct
ath10k_ce_ring
*
src_ring
;
struct
ath10k_ce_ring
*
dest_ring
;
};
struct
ce_sendlist_item
{
...
...
@@ -182,7 +172,7 @@ struct ce_attr;
*
* Implementation note: pushes 1 buffer to Source ring
*/
int
ath10k_ce_send
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_send
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_send_context
,
u32
buffer
,
unsigned
int
nbytes
,
...
...
@@ -190,12 +180,12 @@ int ath10k_ce_send(struct ce_state *ce_state,
unsigned
int
transfer_id
,
unsigned
int
flags
);
void
ath10k_ce_send_cb_register
(
struct
ce_stat
e
*
ce_state
,
void
(
*
send_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
),
void
ath10k_ce_send_cb_register
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
(
*
send_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
),
int
disable_interrupts
);
/* Append a simple buffer (address/length) to a sendlist. */
...
...
@@ -215,7 +205,7 @@ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist,
*
* Implemenation note: Pushes multiple buffers with Gather to Source ring.
*/
int
ath10k_ce_sendlist_send
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_sendlist_send
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_send_context
,
struct
ce_sendlist
*
sendlist
,
/* 14 bits */
...
...
@@ -233,17 +223,17 @@ int ath10k_ce_sendlist_send(struct ce_state *ce_state,
*
* Implemenation note: Pushes a buffer to Dest ring.
*/
int
ath10k_ce_recv_buf_enqueue
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_recv_buf_enqueue
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_recv_context
,
u32
buffer
);
void
ath10k_ce_recv_cb_register
(
struct
ce_stat
e
*
ce_state
,
void
(
*
recv_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
));
void
ath10k_ce_recv_cb_register
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
(
*
recv_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
));
/* recv flags */
/* Data is byte-swapped */
...
...
@@ -253,7 +243,7 @@ void ath10k_ce_recv_cb_register(struct ce_state *ce_state,
* Supply data for the next completed unprocessed receive descriptor.
* Pops buffer from Dest ring.
*/
int
ath10k_ce_completed_recv_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_completed_recv_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
...
...
@@ -263,7 +253,7 @@ int ath10k_ce_completed_recv_next(struct ce_state *ce_state,
* Supply data for the next completed unprocessed send descriptor.
* Pops 1 completed send buffer from Source ring.
*/
int
ath10k_ce_completed_send_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_completed_send_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
...
...
@@ -272,7 +262,7 @@ int ath10k_ce_completed_send_next(struct ce_state *ce_state,
/*==================CE Engine Initialization=======================*/
/* Initialize an instance of a CE */
struct
ce_stat
e
*
ath10k_ce_init
(
struct
ath10k
*
ar
,
struct
ath10k_ce_pip
e
*
ath10k_ce_init
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
const
struct
ce_attr
*
attr
);
...
...
@@ -282,7 +272,7 @@ struct ce_state *ath10k_ce_init(struct ath10k *ar,
* receive buffers. Target DMA must be stopped before using
* this API.
*/
int
ath10k_ce_revoke_recv_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_revoke_recv_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
);
...
...
@@ -291,13 +281,13 @@ int ath10k_ce_revoke_recv_next(struct ce_state *ce_state,
* pending sends. Target DMA must be stopped before using
* this API.
*/
int
ath10k_ce_cancel_send_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_cancel_send_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
unsigned
int
*
transfer_idp
);
void
ath10k_ce_deinit
(
struct
ce_stat
e
*
ce_state
);
void
ath10k_ce_deinit
(
struct
ath10k_ce_pip
e
*
ce_state
);
/*==================CE Interrupt Handlers====================*/
void
ath10k_ce_per_engine_service_any
(
struct
ath10k
*
ar
);
...
...
@@ -322,9 +312,6 @@ struct ce_attr {
/* CE_ATTR_* values */
unsigned
int
flags
;
/* currently not in use */
unsigned
int
priority
;
/* #entries in source ring - Must be a power of 2 */
unsigned
int
src_nentries
;
...
...
@@ -336,9 +323,6 @@ struct ce_attr {
/* #entries in destination ring - Must be a power of 2 */
unsigned
int
dest_nentries
;
/* Future use */
void
*
reserved
;
};
/*
...
...
drivers/net/wireless/ath/ath10k/core.c
浏览文件 @
98497bb2
...
...
@@ -38,17 +38,6 @@ MODULE_PARM_DESC(uart_print, "Uart target debugging");
MODULE_PARM_DESC
(
p2p
,
"Enable ath10k P2P support"
);
static
const
struct
ath10k_hw_params
ath10k_hw_params_list
[]
=
{
{
.
id
=
QCA988X_HW_1_0_VERSION
,
.
name
=
"qca988x hw1.0"
,
.
patch_load_addr
=
QCA988X_HW_1_0_PATCH_LOAD_ADDR
,
.
fw
=
{
.
dir
=
QCA988X_HW_1_0_FW_DIR
,
.
fw
=
QCA988X_HW_1_0_FW_FILE
,
.
otp
=
QCA988X_HW_1_0_OTP_FILE
,
.
board
=
QCA988X_HW_1_0_BOARD_DATA_FILE
,
},
},
{
.
id
=
QCA988X_HW_2_0_VERSION
,
.
name
=
"qca988x hw2.0"
,
...
...
@@ -717,10 +706,43 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
return
0
;
}
int
ath10k_core_register
(
struct
ath10k
*
ar
)
static
int
ath10k_core_check_chip_id
(
struct
ath10k
*
ar
)
{
u32
hw_revision
=
MS
(
ar
->
chip_id
,
SOC_CHIP_ID_REV
);
/* Check that we are not using hw1.0 (some of them have same pci id
* as hw2.0) before doing anything else as ath10k crashes horribly
* due to missing hw1.0 workarounds. */
switch
(
hw_revision
)
{
case
QCA988X_HW_1_0_CHIP_ID_REV
:
ath10k_err
(
"ERROR: qca988x hw1.0 is not supported
\n
"
);
return
-
EOPNOTSUPP
;
case
QCA988X_HW_2_0_CHIP_ID_REV
:
/* known hardware revision, continue normally */
return
0
;
default:
ath10k_warn
(
"Warning: hardware revision unknown (0x%x), expect problems
\n
"
,
ar
->
chip_id
);
return
0
;
}
return
0
;
}
int
ath10k_core_register
(
struct
ath10k
*
ar
,
u32
chip_id
)
{
int
status
;
ar
->
chip_id
=
chip_id
;
status
=
ath10k_core_check_chip_id
(
ar
);
if
(
status
)
{
ath10k_err
(
"Unsupported chip id 0x%08x
\n
"
,
ar
->
chip_id
);
return
status
;
}
status
=
ath10k_core_probe_fw
(
ar
);
if
(
status
)
{
ath10k_err
(
"could not probe fw (%d)
\n
"
,
status
);
...
...
drivers/net/wireless/ath/ath10k/core.h
浏览文件 @
98497bb2
...
...
@@ -270,12 +270,21 @@ enum ath10k_state {
ATH10K_STATE_WEDGED
,
};
enum
ath10k_fw_features
{
/* wmi_mgmt_rx_hdr contains extra RSSI information */
ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX
=
0
,
/* keep last */
ATH10K_FW_FEATURE_COUNT
,
};
struct
ath10k
{
struct
ath_common
ath_common
;
struct
ieee80211_hw
*
hw
;
struct
device
*
dev
;
u8
mac_addr
[
ETH_ALEN
];
u32
chip_id
;
u32
target_version
;
u8
fw_version_major
;
u32
fw_version_minor
;
...
...
@@ -288,6 +297,8 @@ struct ath10k {
u32
vht_cap_info
;
u32
num_rf_chains
;
DECLARE_BITMAP
(
fw_features
,
ATH10K_FW_FEATURE_COUNT
);
struct
targetdef
*
targetdef
;
struct
hostdef
*
hostdef
;
...
...
@@ -393,7 +404,7 @@ void ath10k_core_destroy(struct ath10k *ar);
int
ath10k_core_start
(
struct
ath10k
*
ar
);
void
ath10k_core_stop
(
struct
ath10k
*
ar
);
int
ath10k_core_register
(
struct
ath10k
*
ar
);
int
ath10k_core_register
(
struct
ath10k
*
ar
,
u32
chip_id
);
void
ath10k_core_unregister
(
struct
ath10k
*
ar
);
#endif
/* _CORE_H_ */
drivers/net/wireless/ath/ath10k/debug.c
浏览文件 @
98497bb2
...
...
@@ -260,7 +260,6 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
}
spin_unlock_bh
(
&
ar
->
data_lock
);
mutex_unlock
(
&
ar
->
conf_mutex
);
complete
(
&
ar
->
debug
.
event_stats_compl
);
}
...
...
@@ -499,6 +498,25 @@ static const struct file_operations fops_simulate_fw_crash = {
.
llseek
=
default_llseek
,
};
static
ssize_t
ath10k_read_chip_id
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
unsigned
int
len
;
char
buf
[
50
];
len
=
scnprintf
(
buf
,
sizeof
(
buf
),
"0x%08x
\n
"
,
ar
->
chip_id
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
len
);
}
static
const
struct
file_operations
fops_chip_id
=
{
.
read
=
ath10k_read_chip_id
,
.
open
=
simple_open
,
.
owner
=
THIS_MODULE
,
.
llseek
=
default_llseek
,
};
int
ath10k_debug_create
(
struct
ath10k
*
ar
)
{
ar
->
debug
.
debugfs_phy
=
debugfs_create_dir
(
"ath10k"
,
...
...
@@ -518,6 +536,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
(
"chip_id"
,
S_IRUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_chip_id
);
return
0
;
}
#endif
/* CONFIG_ATH10K_DEBUGFS */
...
...
drivers/net/wireless/ath/ath10k/htc.c
浏览文件 @
98497bb2
...
...
@@ -772,16 +772,16 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
flags
|=
SM
(
tx_alloc
,
ATH10K_HTC_CONN_FLAGS_RECV_ALLOC
);
req_msg
=
&
msg
->
connect_service
;
req_msg
->
flags
=
__cpu_to_le16
(
flags
);
req_msg
->
service_id
=
__cpu_to_le16
(
conn_req
->
service_id
);
/* Only enable credit flow control for WMI ctrl service */
if
(
conn_req
->
service_id
!=
ATH10K_HTC_SVC_ID_WMI_CONTROL
)
{
flags
|=
ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL
;
disable_credit_flow_ctrl
=
true
;
}
req_msg
=
&
msg
->
connect_service
;
req_msg
->
flags
=
__cpu_to_le16
(
flags
);
req_msg
->
service_id
=
__cpu_to_le16
(
conn_req
->
service_id
);
INIT_COMPLETION
(
htc
->
ctl_resp
);
status
=
ath10k_htc_send
(
htc
,
ATH10K_HTC_EP_0
,
skb
);
...
...
drivers/net/wireless/ath/ath10k/htt.c
浏览文件 @
98497bb2
...
...
@@ -104,21 +104,16 @@ int ath10k_htt_attach(struct ath10k *ar)
static
int
ath10k_htt_verify_version
(
struct
ath10k_htt
*
htt
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt target version %d.%d; host version %d.%d
\n
"
,
htt
->
target_version_major
,
htt
->
target_version_minor
,
HTT_CURRENT_VERSION_MAJOR
,
HTT_CURRENT_VERSION_MINOR
);
if
(
htt
->
target_version_major
!=
HTT_CURRENT_VERSION_MAJOR
)
{
ath10k_err
(
"htt major versions are incompatible!
\n
"
);
ath10k_info
(
"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
"
,
htt
->
target_version_major
);
return
-
ENOTSUPP
;
}
if
(
htt
->
target_version_minor
!=
HTT_CURRENT_VERSION_MINOR
)
ath10k_warn
(
"htt minor version differ but still compatible
\n
"
);
return
0
;
}
...
...
drivers/net/wireless/ath/ath10k/htt.h
浏览文件 @
98497bb2
...
...
@@ -23,9 +23,6 @@
#include "htc.h"
#include "rx_desc.h"
#define HTT_CURRENT_VERSION_MAJOR 2
#define HTT_CURRENT_VERSION_MINOR 1
enum
htt_dbg_stats_type
{
HTT_DBG_STATS_WAL_PDEV_TXRX
=
1
<<
0
,
HTT_DBG_STATS_RX_REORDER
=
1
<<
1
,
...
...
@@ -45,6 +42,9 @@ enum htt_h2t_msg_type { /* host-to-target */
HTT_H2T_MSG_TYPE_SYNC
=
4
,
HTT_H2T_MSG_TYPE_AGGR_CFG
=
5
,
HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG
=
6
,
/* This command is used for sending management frames in HTT < 3.0.
* HTT >= 3.0 uses TX_FRM for everything. */
HTT_H2T_MSG_TYPE_MGMT_TX
=
7
,
HTT_H2T_NUM_MSGS
/* keep this last */
...
...
drivers/net/wireless/ath/ath10k/htt_rx.c
浏览文件 @
98497bb2
...
...
@@ -610,8 +610,7 @@ static int ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
RX_MPDU_START_INFO0_ENCRYPT_TYPE
);
/* FIXME: No idea what assumptions are safe here. Need logs */
if
((
fmt
==
RX_MSDU_DECAP_RAW
&&
skb
->
next
)
||
(
fmt
==
RX_MSDU_DECAP_8023_SNAP_LLC
))
{
if
((
fmt
==
RX_MSDU_DECAP_RAW
&&
skb
->
next
))
{
ath10k_htt_rx_free_msdu_chain
(
skb
->
next
);
skb
->
next
=
NULL
;
return
-
ENOTSUPP
;
...
...
@@ -659,6 +658,15 @@ static int ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
decap_hdr
+=
roundup
(
crypto_len
,
4
);
}
/* When fmt == RX_MSDU_DECAP_8023_SNAP_LLC:
*
* SNAP 802.3 consists of:
* [dst:6][src:6][len:2][dsap:1][ssap:1][ctl:1][snap:5]
* [data][fcs:4].
*
* Since this overlaps with A-MSDU header (da, sa, len)
* there's nothing extra to do. */
if
(
fmt
==
RX_MSDU_DECAP_ETHERNET2_DIX
)
{
/* Ethernet2 decap inserts ethernet header in place of
* A-MSDU subframe header. */
...
...
drivers/net/wireless/ath/ath10k/htt_tx.c
浏览文件 @
98497bb2
...
...
@@ -401,10 +401,16 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
goto
err
;
}
txfrag
=
dev_alloc_skb
(
frag_len
);
if
(
!
txfrag
)
{
res
=
-
ENOMEM
;
goto
err
;
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
<
3
||
!
ieee80211_is_mgmt
(
hdr
->
frame_control
))
{
txfrag
=
dev_alloc_skb
(
frag_len
);
if
(
!
txfrag
)
{
res
=
-
ENOMEM
;
goto
err
;
}
}
if
(
!
IS_ALIGNED
((
unsigned
long
)
txdesc
->
data
,
4
))
{
...
...
@@ -427,23 +433,31 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if
(
res
)
goto
err
;
/* tx fragment list must be terminated with zero-entry */
skb_put
(
txfrag
,
frag_len
);
tx_frags
=
(
struct
htt_data_tx_desc_frag
*
)
txfrag
->
data
;
tx_frags
[
0
].
paddr
=
__cpu_to_le32
(
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
tx_frags
[
0
].
len
=
__cpu_to_le32
(
msdu
->
len
);
tx_frags
[
1
].
paddr
=
__cpu_to_le32
(
0
);
tx_frags
[
1
].
len
=
__cpu_to_le32
(
0
);
res
=
ath10k_skb_map
(
dev
,
txfrag
);
if
(
res
)
goto
err
;
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
<
3
||
!
ieee80211_is_mgmt
(
hdr
->
frame_control
))
{
/* tx fragment list must be terminated with zero-entry */
skb_put
(
txfrag
,
frag_len
);
tx_frags
=
(
struct
htt_data_tx_desc_frag
*
)
txfrag
->
data
;
tx_frags
[
0
].
paddr
=
__cpu_to_le32
(
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
tx_frags
[
0
].
len
=
__cpu_to_le32
(
msdu
->
len
);
tx_frags
[
1
].
paddr
=
__cpu_to_le32
(
0
);
tx_frags
[
1
].
len
=
__cpu_to_le32
(
0
);
res
=
ath10k_skb_map
(
dev
,
txfrag
);
if
(
res
)
goto
err
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
"txfrag 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
txfrag
)
->
paddr
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"txfrag: "
,
txfrag
->
data
,
frag_len
);
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
"txfrag 0x%llx msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
txfrag
)
->
paddr
,
ath10k_dbg
(
ATH10K_DBG_HTT
,
"msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"txfrag: "
,
txfrag
->
data
,
frag_len
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"msdu: "
,
msdu
->
data
,
msdu
->
len
);
...
...
@@ -459,8 +473,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if
(
!
ieee80211_has_protected
(
hdr
->
frame_control
))
flags0
|=
HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT
;
flags0
|=
HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT
;
flags0
|=
SM
(
ATH10K_HW_TXRX_NATIVE_WIFI
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
>=
3
&&
ieee80211_is_mgmt
(
hdr
->
frame_control
))
flags0
|=
SM
(
ATH10K_HW_TXRX_MGMT
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
else
flags0
|=
SM
(
ATH10K_HW_TXRX_NATIVE_WIFI
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
flags1
=
0
;
flags1
|=
SM
((
u16
)
vdev_id
,
HTT_DATA_TX_DESC_FLAGS1_VDEV_ID
);
...
...
@@ -468,7 +491,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
flags1
|=
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD
;
flags1
|=
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD
;
frags_paddr
=
ATH10K_SKB_CB
(
txfrag
)
->
paddr
;
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
>=
3
&&
ieee80211_is_mgmt
(
hdr
->
frame_control
))
frags_paddr
=
ATH10K_SKB_CB
(
msdu
)
->
paddr
;
else
frags_paddr
=
ATH10K_SKB_CB
(
txfrag
)
->
paddr
;
cmd
->
hdr
.
msg_type
=
HTT_H2T_MSG_TYPE_TX_FRM
;
cmd
->
data_tx
.
flags0
=
flags0
;
...
...
drivers/net/wireless/ath/ath10k/hw.h
浏览文件 @
98497bb2
...
...
@@ -24,18 +24,14 @@
#define SUPPORTED_FW_MAJOR 1
#define SUPPORTED_FW_MINOR 0
#define SUPPORTED_FW_RELEASE 0
#define SUPPORTED_FW_BUILD 6
29
#define SUPPORTED_FW_BUILD 6
36
/* QCA988X 1.0 definitions */
#define QCA988X_HW_1_0_VERSION 0x4000002c
#define QCA988X_HW_1_0_FW_DIR "ath10k/QCA988X/hw1.0"
#define QCA988X_HW_1_0_FW_FILE "firmware.bin"
#define QCA988X_HW_1_0_OTP_FILE "otp.bin"
#define QCA988X_HW_1_0_BOARD_DATA_FILE "board.bin"
#define QCA988X_HW_1_0_PATCH_LOAD_ADDR 0x1234
/* QCA988X 1.0 definitions (unsupported) */
#define QCA988X_HW_1_0_CHIP_ID_REV 0x0
/* QCA988X 2.0 definitions */
#define QCA988X_HW_2_0_VERSION 0x4100016c
#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_OTP_FILE "otp.bin"
...
...
@@ -53,6 +49,9 @@ enum ath10k_hw_txrx_mode {
ATH10K_HW_TXRX_RAW
=
0
,
ATH10K_HW_TXRX_NATIVE_WIFI
=
1
,
ATH10K_HW_TXRX_ETHERNET
=
2
,
/* Valid for HTT >= 3.0. Used for management frames in TX_FRM. */
ATH10K_HW_TXRX_MGMT
=
3
,
};
enum
ath10k_mcast2ucast_mode
{
...
...
@@ -169,6 +168,10 @@ enum ath10k_mcast2ucast_mode {
#define SOC_LPO_CAL_ENABLE_LSB 20
#define SOC_LPO_CAL_ENABLE_MASK 0x00100000
#define SOC_CHIP_ID_ADDRESS 0x000000ec
#define SOC_CHIP_ID_REV_LSB 8
#define SOC_CHIP_ID_REV_MASK 0x00000f00
#define WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008
#define WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004
#define WLAN_SYSTEM_SLEEP_DISABLE_LSB 0
...
...
drivers/net/wireless/ath/ath10k/mac.c
浏览文件 @
98497bb2
...
...
@@ -503,13 +503,10 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
{
struct
ieee80211_channel
*
channel
=
ar
->
hw
->
conf
.
chandef
.
chan
;
struct
wmi_vdev_start_request_arg
arg
=
{};
enum
nl80211_channel_type
type
;
int
ret
=
0
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
type
=
cfg80211_get_chandef_type
(
&
ar
->
hw
->
conf
.
chandef
);
arg
.
vdev_id
=
vdev_id
;
arg
.
channel
.
freq
=
channel
->
center_freq
;
arg
.
channel
.
band_center_freq1
=
ar
->
hw
->
conf
.
chandef
.
center_freq1
;
...
...
@@ -973,7 +970,7 @@ static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar,
sta
->
uapsd_queues
,
sta
->
max_sp
);
arg
->
peer_flags
|=
WMI_PEER_APSD
;
arg
->
peer_
flag
s
|=
WMI_RC_UAPSD_FLAG
;
arg
->
peer_
rate_cap
s
|=
WMI_RC_UAPSD_FLAG
;
if
(
sta
->
uapsd_queues
&
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
)
uapsd
|=
WMI_AP_PS_UAPSD_AC3_DELIVERY_EN
|
...
...
@@ -1421,10 +1418,6 @@ static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)
struct
ieee80211_key_conf
*
key
=
info
->
control
.
hw_key
;
int
ret
;
/* TODO AP mode should be implemented */
if
(
vif
->
type
!=
NL80211_IFTYPE_STATION
)
return
;
if
(
!
ieee80211_has_protected
(
hdr
->
frame_control
))
return
;
...
...
@@ -1480,6 +1473,12 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
int
ret
;
if
(
ar
->
htt
.
target_version_major
>=
3
)
{
/* Since HTT 3.0 there is no separate mgmt tx command */
ret
=
ath10k_htt_tx
(
&
ar
->
htt
,
skb
);
goto
exit
;
}
if
(
ieee80211_is_mgmt
(
hdr
->
frame_control
))
ret
=
ath10k_htt_mgmt_tx
(
&
ar
->
htt
,
skb
);
else
if
(
ieee80211_is_nullfunc
(
hdr
->
frame_control
))
...
...
@@ -1491,6 +1490,7 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
else
ret
=
ath10k_htt_tx
(
&
ar
->
htt
,
skb
);
exit:
if
(
ret
)
{
ath10k_warn
(
"tx failed (%d). dropping packet.
\n
"
,
ret
);
ieee80211_free_txskb
(
ar
->
hw
,
skb
);
...
...
@@ -1727,8 +1727,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,
/* we must calculate tid before we apply qos workaround
* as we'd lose the qos control field */
tid
=
HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST
;
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
)
&&
is_unicast_ether_addr
(
ieee80211_get_DA
(
hdr
)))
{
if
(
ieee80211_is_mgmt
(
hdr
->
frame_control
))
{
tid
=
HTT_DATA_TX_EXT_TID_MGMT
;
}
else
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
)
&&
is_unicast_ether_addr
(
ieee80211_get_DA
(
hdr
)))
{
u8
*
qc
=
ieee80211_get_qos_ctl
(
hdr
);
tid
=
qc
[
0
]
&
IEEE80211_QOS_CTL_TID_MASK
;
}
...
...
drivers/net/wireless/ath/ath10k/pci.c
浏览文件 @
98497bb2
...
...
@@ -36,11 +36,9 @@ static unsigned int ath10k_target_ps;
module_param
(
ath10k_target_ps
,
uint
,
0644
);
MODULE_PARM_DESC
(
ath10k_target_ps
,
"Enable ath10k Target (SoC) PS option"
);
#define QCA988X_1_0_DEVICE_ID (0xabcd)
#define QCA988X_2_0_DEVICE_ID (0x003c)
static
DEFINE_PCI_DEVICE_TABLE
(
ath10k_pci_id_table
)
=
{
{
PCI_VDEVICE
(
ATHEROS
,
QCA988X_1_0_DEVICE_ID
)
},
/* PCI-E QCA988X V1 */
{
PCI_VDEVICE
(
ATHEROS
,
QCA988X_2_0_DEVICE_ID
)
},
/* PCI-E QCA988X V2 */
{
0
}
};
...
...
@@ -50,9 +48,9 @@ static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address,
static
void
ath10k_pci_process_ce
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_post_rx
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_post_rx_pipe
(
struct
hif_ce_pipe_info
*
pipe_info
,
static
int
ath10k_pci_post_rx_pipe
(
struct
ath10k_pci_pipe
*
pipe_info
,
int
num
);
static
void
ath10k_pci_rx_pipe_cleanup
(
struct
hif_ce_pipe_info
*
pipe_info
);
static
void
ath10k_pci_rx_pipe_cleanup
(
struct
ath10k_pci_pipe
*
pipe_info
);
static
void
ath10k_pci_stop_ce
(
struct
ath10k
*
ar
);
static
void
ath10k_pci_device_reset
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_reset_target
(
struct
ath10k
*
ar
);
...
...
@@ -60,43 +58,145 @@ static int ath10k_pci_start_intr(struct ath10k *ar);
static
void
ath10k_pci_stop_intr
(
struct
ath10k
*
ar
);
static
const
struct
ce_attr
host_ce_config_wlan
[]
=
{
/* host->target HTC control and raw streams */
{
/* CE0 */
CE_ATTR_FLAGS
,
0
,
16
,
256
,
0
,
NULL
,},
/* could be moved to share CE3 */
/* target->host HTT + HTC control */
{
/* CE1 */
CE_ATTR_FLAGS
,
0
,
0
,
512
,
512
,
NULL
,},
/* target->host WMI */
{
/* CE2 */
CE_ATTR_FLAGS
,
0
,
0
,
2048
,
32
,
NULL
,},
/* host->target WMI */
{
/* CE3 */
CE_ATTR_FLAGS
,
0
,
32
,
2048
,
0
,
NULL
,},
/* host->target HTT */
{
/* CE4 */
CE_ATTR_FLAGS
|
CE_ATTR_DIS_INTR
,
0
,
CE_HTT_H2T_MSG_SRC_NENTRIES
,
256
,
0
,
NULL
,},
/* unused */
{
/* CE5 */
CE_ATTR_FLAGS
,
0
,
0
,
0
,
0
,
NULL
,},
/* Target autonomous hif_memcpy */
{
/* CE6 */
CE_ATTR_FLAGS
,
0
,
0
,
0
,
0
,
NULL
,},
/* ce_diag, the Diagnostic Window */
{
/* CE7 */
CE_ATTR_FLAGS
,
0
,
2
,
DIAG_TRANSFER_LIMIT
,
2
,
NULL
,},
/* CE0: host->target HTC control and raw streams */
{
.
flags
=
CE_ATTR_FLAGS
,
.
src_nentries
=
16
,
.
src_sz_max
=
256
,
.
dest_nentries
=
0
,
},
/* CE1: target->host HTT + HTC control */
{
.
flags
=
CE_ATTR_FLAGS
,
.
src_nentries
=
0
,
.
src_sz_max
=
512
,
.
dest_nentries
=
512
,
},
/* CE2: target->host WMI */
{
.
flags
=
CE_ATTR_FLAGS
,
.
src_nentries
=
0
,
.
src_sz_max
=
2048
,
.
dest_nentries
=
32
,
},
/* CE3: host->target WMI */
{
.
flags
=
CE_ATTR_FLAGS
,
.
src_nentries
=
32
,
.
src_sz_max
=
2048
,
.
dest_nentries
=
0
,
},
/* CE4: host->target HTT */
{
.
flags
=
CE_ATTR_FLAGS
|
CE_ATTR_DIS_INTR
,
.
src_nentries
=
CE_HTT_H2T_MSG_SRC_NENTRIES
,
.
src_sz_max
=
256
,
.
dest_nentries
=
0
,
},
/* CE5: unused */
{
.
flags
=
CE_ATTR_FLAGS
,
.
src_nentries
=
0
,
.
src_sz_max
=
0
,
.
dest_nentries
=
0
,
},
/* CE6: target autonomous hif_memcpy */
{
.
flags
=
CE_ATTR_FLAGS
,
.
src_nentries
=
0
,
.
src_sz_max
=
0
,
.
dest_nentries
=
0
,
},
/* CE7: ce_diag, the Diagnostic Window */
{
.
flags
=
CE_ATTR_FLAGS
,
.
src_nentries
=
2
,
.
src_sz_max
=
DIAG_TRANSFER_LIMIT
,
.
dest_nentries
=
2
,
},
};
/* Target firmware's Copy Engine configuration. */
static
const
struct
ce_pipe_config
target_ce_config_wlan
[]
=
{
/* host->target HTC control and raw streams */
{
/* CE0 */
0
,
PIPEDIR_OUT
,
32
,
256
,
CE_ATTR_FLAGS
,
0
,},
/* target->host HTT + HTC control */
{
/* CE1 */
1
,
PIPEDIR_IN
,
32
,
512
,
CE_ATTR_FLAGS
,
0
,},
/* target->host WMI */
{
/* CE2 */
2
,
PIPEDIR_IN
,
32
,
2048
,
CE_ATTR_FLAGS
,
0
,},
/* host->target WMI */
{
/* CE3 */
3
,
PIPEDIR_OUT
,
32
,
2048
,
CE_ATTR_FLAGS
,
0
,},
/* host->target HTT */
{
/* CE4 */
4
,
PIPEDIR_OUT
,
256
,
256
,
CE_ATTR_FLAGS
,
0
,},
/* CE0: host->target HTC control and raw streams */
{
.
pipenum
=
0
,
.
pipedir
=
PIPEDIR_OUT
,
.
nentries
=
32
,
.
nbytes_max
=
256
,
.
flags
=
CE_ATTR_FLAGS
,
.
reserved
=
0
,
},
/* CE1: target->host HTT + HTC control */
{
.
pipenum
=
1
,
.
pipedir
=
PIPEDIR_IN
,
.
nentries
=
32
,
.
nbytes_max
=
512
,
.
flags
=
CE_ATTR_FLAGS
,
.
reserved
=
0
,
},
/* CE2: target->host WMI */
{
.
pipenum
=
2
,
.
pipedir
=
PIPEDIR_IN
,
.
nentries
=
32
,
.
nbytes_max
=
2048
,
.
flags
=
CE_ATTR_FLAGS
,
.
reserved
=
0
,
},
/* CE3: host->target WMI */
{
.
pipenum
=
3
,
.
pipedir
=
PIPEDIR_OUT
,
.
nentries
=
32
,
.
nbytes_max
=
2048
,
.
flags
=
CE_ATTR_FLAGS
,
.
reserved
=
0
,
},
/* CE4: host->target HTT */
{
.
pipenum
=
4
,
.
pipedir
=
PIPEDIR_OUT
,
.
nentries
=
256
,
.
nbytes_max
=
256
,
.
flags
=
CE_ATTR_FLAGS
,
.
reserved
=
0
,
},
/* NB: 50% of src nentries, since tx has 2 frags */
/* unused */
{
/* CE5 */
5
,
PIPEDIR_OUT
,
32
,
2048
,
CE_ATTR_FLAGS
,
0
,},
/* Reserved for target autonomous hif_memcpy */
{
/* CE6 */
6
,
PIPEDIR_INOUT
,
32
,
4096
,
CE_ATTR_FLAGS
,
0
,},
/* CE5: unused */
{
.
pipenum
=
5
,
.
pipedir
=
PIPEDIR_OUT
,
.
nentries
=
32
,
.
nbytes_max
=
2048
,
.
flags
=
CE_ATTR_FLAGS
,
.
reserved
=
0
,
},
/* CE6: Reserved for target autonomous hif_memcpy */
{
.
pipenum
=
6
,
.
pipedir
=
PIPEDIR_INOUT
,
.
nentries
=
32
,
.
nbytes_max
=
4096
,
.
flags
=
CE_ATTR_FLAGS
,
.
reserved
=
0
,
},
/* CE7 used only by Host */
};
...
...
@@ -114,7 +214,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
unsigned
int
completed_nbytes
,
orig_nbytes
,
remaining_bytes
;
unsigned
int
id
;
unsigned
int
flags
;
struct
ce_stat
e
*
ce_diag
;
struct
ath10k_ce_pip
e
*
ce_diag
;
/* Host buffer address in CE space */
u32
ce_data
;
dma_addr_t
ce_data_base
=
0
;
...
...
@@ -278,7 +378,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
unsigned
int
completed_nbytes
,
orig_nbytes
,
remaining_bytes
;
unsigned
int
id
;
unsigned
int
flags
;
struct
ce_stat
e
*
ce_diag
;
struct
ath10k_ce_pip
e
*
ce_diag
;
void
*
data_buf
=
NULL
;
u32
ce_data
;
/* Host buffer address in CE space */
dma_addr_t
ce_data_base
=
0
;
...
...
@@ -437,7 +537,7 @@ static void ath10k_pci_wait(struct ath10k *ar)
ath10k_warn
(
"Unable to wakeup target
\n
"
);
}
void
ath10k_do_pci_wake
(
struct
ath10k
*
ar
)
int
ath10k_do_pci_wake
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
void
__iomem
*
pci_addr
=
ar_pci
->
mem
;
...
...
@@ -453,18 +553,19 @@ void ath10k_do_pci_wake(struct ath10k *ar)
atomic_inc
(
&
ar_pci
->
keep_awake_count
);
if
(
ar_pci
->
verified_awake
)
return
;
return
0
;
for
(;;)
{
if
(
ath10k_pci_target_is_awake
(
ar
))
{
ar_pci
->
verified_awake
=
true
;
break
;
return
0
;
}
if
(
tot_delay
>
PCIE_WAKE_TIMEOUT
)
{
ath10k_warn
(
"target takes too long to wake up (awake count %d)
\n
"
,
ath10k_warn
(
"target took longer %d us to wake up (awake count %d)
\n
"
,
PCIE_WAKE_TIMEOUT
,
atomic_read
(
&
ar_pci
->
keep_awake_count
));
break
;
return
-
ETIMEDOUT
;
}
udelay
(
curr_delay
);
...
...
@@ -493,7 +594,7 @@ void ath10k_do_pci_sleep(struct ath10k *ar)
* FIXME: Handle OOM properly.
*/
static
inline
struct
ath10k_pci_compl
*
get_free_compl
(
struct
hif_ce_pipe_info
*
pipe_info
)
struct
ath10k_pci_compl
*
get_free_compl
(
struct
ath10k_pci_pipe
*
pipe_info
)
{
struct
ath10k_pci_compl
*
compl
=
NULL
;
...
...
@@ -511,7 +612,7 @@ struct ath10k_pci_compl *get_free_compl(struct hif_ce_pipe_info *pipe_info)
}
/* Called by lower (CE) layer when a send to Target completes. */
static
void
ath10k_pci_ce_send_done
(
struct
ce_stat
e
*
ce_state
,
static
void
ath10k_pci_ce_send_done
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
ce_data
,
unsigned
int
nbytes
,
...
...
@@ -519,7 +620,7 @@ static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
hif_ce_pipe_info
*
pipe_info
=
&
ar_pci
->
pipe_info
[
ce_state
->
id
];
struct
ath10k_pci_pipe
*
pipe_info
=
&
ar_pci
->
pipe_info
[
ce_state
->
id
];
struct
ath10k_pci_compl
*
compl
;
bool
process
=
false
;
...
...
@@ -540,10 +641,10 @@ static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
if
(
!
compl
)
break
;
compl
->
s
end_or_recv
=
HIF_CE_COMPLETE
_SEND
;
compl
->
s
tate
=
ATH10K_PCI_COMPL
_SEND
;
compl
->
ce_state
=
ce_state
;
compl
->
pipe_info
=
pipe_info
;
compl
->
transfer_context
=
transfer_context
;
compl
->
skb
=
transfer_context
;
compl
->
nbytes
=
nbytes
;
compl
->
transfer_id
=
transfer_id
;
compl
->
flags
=
0
;
...
...
@@ -573,7 +674,7 @@ static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
}
/* Called by lower (CE) layer when data is received from the Target. */
static
void
ath10k_pci_ce_recv_data
(
struct
ce_stat
e
*
ce_state
,
static
void
ath10k_pci_ce_recv_data
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
ce_data
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
...
...
@@ -581,7 +682,7 @@ static void ath10k_pci_ce_recv_data(struct ce_state *ce_state,
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
hif_ce_pipe_info
*
pipe_info
=
&
ar_pci
->
pipe_info
[
ce_state
->
id
];
struct
ath10k_pci_pipe
*
pipe_info
=
&
ar_pci
->
pipe_info
[
ce_state
->
id
];
struct
ath10k_pci_compl
*
compl
;
struct
sk_buff
*
skb
;
...
...
@@ -590,10 +691,10 @@ static void ath10k_pci_ce_recv_data(struct ce_state *ce_state,
if
(
!
compl
)
break
;
compl
->
s
end_or_recv
=
HIF_CE_COMPLETE
_RECV
;
compl
->
s
tate
=
ATH10K_PCI_COMPL
_RECV
;
compl
->
ce_state
=
ce_state
;
compl
->
pipe_info
=
pipe_info
;
compl
->
transfer_context
=
transfer_context
;
compl
->
skb
=
transfer_context
;
compl
->
nbytes
=
nbytes
;
compl
->
transfer_id
=
transfer_id
;
compl
->
flags
=
flags
;
...
...
@@ -625,8 +726,8 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id,
{
struct
ath10k_skb_cb
*
skb_cb
=
ATH10K_SKB_CB
(
nbuf
);
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
hif_ce_pipe_info
*
pipe_info
=
&
(
ar_pci
->
pipe_info
[
pipe_id
]);
struct
ce_stat
e
*
ce_hdl
=
pipe_info
->
ce_hdl
;
struct
ath10k_pci_pipe
*
pipe_info
=
&
(
ar_pci
->
pipe_info
[
pipe_id
]);
struct
ath10k_ce_pip
e
*
ce_hdl
=
pipe_info
->
ce_hdl
;
struct
ce_sendlist
sendlist
;
unsigned
int
len
;
u32
flags
=
0
;
...
...
@@ -670,7 +771,7 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id,
static
u16
ath10k_pci_hif_get_free_queue_number
(
struct
ath10k
*
ar
,
u8
pipe
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
hif_ce_pipe_info
*
pipe_info
=
&
(
ar_pci
->
pipe_info
[
pipe
]);
struct
ath10k_pci_pipe
*
pipe_info
=
&
(
ar_pci
->
pipe_info
[
pipe
]);
int
ret
;
spin_lock_bh
(
&
pipe_info
->
pipe_lock
);
...
...
@@ -764,9 +865,9 @@ static void ath10k_pci_hif_set_callbacks(struct ath10k *ar,
static
int
ath10k_pci_start_ce
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ce_stat
e
*
ce_diag
=
ar_pci
->
ce_diag
;
struct
ath10k_ce_pip
e
*
ce_diag
=
ar_pci
->
ce_diag
;
const
struct
ce_attr
*
attr
;
struct
hif_ce_pipe_info
*
pipe_info
;
struct
ath10k_pci_pipe
*
pipe_info
;
struct
ath10k_pci_compl
*
compl
;
int
i
,
pipe_num
,
completions
,
disable_interrupts
;
...
...
@@ -805,15 +906,14 @@ static int ath10k_pci_start_ce(struct ath10k *ar)
continue
;
for
(
i
=
0
;
i
<
completions
;
i
++
)
{
compl
=
kmalloc
(
sizeof
(
struct
ath10k_pci_compl
),
GFP_KERNEL
);
compl
=
kmalloc
(
sizeof
(
*
compl
),
GFP_KERNEL
);
if
(
!
compl
)
{
ath10k_warn
(
"No memory for completion state
\n
"
);
ath10k_pci_stop_ce
(
ar
);
return
-
ENOMEM
;
}
compl
->
s
end_or_recv
=
HIF_CE_COMPLETE
_FREE
;
compl
->
s
tate
=
ATH10K_PCI_COMPL
_FREE
;
list_add_tail
(
&
compl
->
list
,
&
pipe_info
->
compl_free
);
}
}
...
...
@@ -840,7 +940,7 @@ static void ath10k_pci_stop_ce(struct ath10k *ar)
* their associated resources */
spin_lock_bh
(
&
ar_pci
->
compl_lock
);
list_for_each_entry
(
compl
,
&
ar_pci
->
compl_process
,
list
)
{
skb
=
(
struct
sk_buff
*
)
compl
->
transfer_context
;
skb
=
compl
->
skb
;
ATH10K_SKB_CB
(
skb
)
->
is_aborted
=
true
;
}
spin_unlock_bh
(
&
ar_pci
->
compl_lock
);
...
...
@@ -850,7 +950,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ath10k_pci_compl
*
compl
,
*
tmp
;
struct
hif_ce_pipe_info
*
pipe_info
;
struct
ath10k_pci_pipe
*
pipe_info
;
struct
sk_buff
*
netbuf
;
int
pipe_num
;
...
...
@@ -861,7 +961,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar)
list_for_each_entry_safe
(
compl
,
tmp
,
&
ar_pci
->
compl_process
,
list
)
{
list_del
(
&
compl
->
list
);
netbuf
=
(
struct
sk_buff
*
)
compl
->
transfer_context
;
netbuf
=
compl
->
skb
;
dev_kfree_skb_any
(
netbuf
);
kfree
(
compl
);
}
...
...
@@ -912,12 +1012,14 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
list_del
(
&
compl
->
list
);
spin_unlock_bh
(
&
ar_pci
->
compl_lock
);
if
(
compl
->
send_or_recv
==
HIF_CE_COMPLETE_SEND
)
{
switch
(
compl
->
state
)
{
case
ATH10K_PCI_COMPL_SEND
:
cb
->
tx_completion
(
ar
,
compl
->
transfer_context
,
compl
->
skb
,
compl
->
transfer_id
);
send_done
=
1
;
}
else
{
break
;
case
ATH10K_PCI_COMPL_RECV
:
ret
=
ath10k_pci_post_rx_pipe
(
compl
->
pipe_info
,
1
);
if
(
ret
)
{
ath10k_warn
(
"Unable to post recv buffer for pipe: %d
\n
"
,
...
...
@@ -925,7 +1027,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
break
;
}
skb
=
(
struct
sk_buff
*
)
compl
->
transfer_context
;
skb
=
compl
->
skb
;
nbytes
=
compl
->
nbytes
;
ath10k_dbg
(
ATH10K_DBG_PCI
,
...
...
@@ -944,9 +1046,17 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
nbytes
,
skb
->
len
+
skb_tailroom
(
skb
));
}
break
;
case
ATH10K_PCI_COMPL_FREE
:
ath10k_warn
(
"free completion cannot be processed
\n
"
);
break
;
default:
ath10k_warn
(
"invalid completion state (%d)
\n
"
,
compl
->
state
);
break
;
}
compl
->
s
end_or_recv
=
HIF_CE_COMPLETE
_FREE
;
compl
->
s
tate
=
ATH10K_PCI_COMPL
_FREE
;
/*
* Add completion back to the pipe's free list.
...
...
@@ -1037,12 +1147,12 @@ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
&
dl_is_polled
);
}
static
int
ath10k_pci_post_rx_pipe
(
struct
hif_ce_pipe_info
*
pipe_info
,
static
int
ath10k_pci_post_rx_pipe
(
struct
ath10k_pci_pipe
*
pipe_info
,
int
num
)
{
struct
ath10k
*
ar
=
pipe_info
->
hif_ce_state
;
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ce_stat
e
*
ce_state
=
pipe_info
->
ce_hdl
;
struct
ath10k_ce_pip
e
*
ce_state
=
pipe_info
->
ce_hdl
;
struct
sk_buff
*
skb
;
dma_addr_t
ce_data
;
int
i
,
ret
=
0
;
...
...
@@ -1097,7 +1207,7 @@ static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info,
static
int
ath10k_pci_post_rx
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
hif_ce_pipe_info
*
pipe_info
;
struct
ath10k_pci_pipe
*
pipe_info
;
const
struct
ce_attr
*
attr
;
int
pipe_num
,
ret
=
0
;
...
...
@@ -1147,11 +1257,11 @@ static int ath10k_pci_hif_start(struct ath10k *ar)
return
0
;
}
static
void
ath10k_pci_rx_pipe_cleanup
(
struct
hif_ce_pipe_info
*
pipe_info
)
static
void
ath10k_pci_rx_pipe_cleanup
(
struct
ath10k_pci_pipe
*
pipe_info
)
{
struct
ath10k
*
ar
;
struct
ath10k_pci
*
ar_pci
;
struct
ce_stat
e
*
ce_hdl
;
struct
ath10k_ce_pip
e
*
ce_hdl
;
u32
buf_sz
;
struct
sk_buff
*
netbuf
;
u32
ce_data
;
...
...
@@ -1179,11 +1289,11 @@ static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info)
}
}
static
void
ath10k_pci_tx_pipe_cleanup
(
struct
hif_ce_pipe_info
*
pipe_info
)
static
void
ath10k_pci_tx_pipe_cleanup
(
struct
ath10k_pci_pipe
*
pipe_info
)
{
struct
ath10k
*
ar
;
struct
ath10k_pci
*
ar_pci
;
struct
ce_stat
e
*
ce_hdl
;
struct
ath10k_ce_pip
e
*
ce_hdl
;
struct
sk_buff
*
netbuf
;
u32
ce_data
;
unsigned
int
nbytes
;
...
...
@@ -1232,7 +1342,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
int
pipe_num
;
for
(
pipe_num
=
0
;
pipe_num
<
ar_pci
->
ce_count
;
pipe_num
++
)
{
struct
hif_ce_pipe_info
*
pipe_info
;
struct
ath10k_pci_pipe
*
pipe_info
;
pipe_info
=
&
ar_pci
->
pipe_info
[
pipe_num
];
ath10k_pci_rx_pipe_cleanup
(
pipe_info
);
...
...
@@ -1243,7 +1353,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
static
void
ath10k_pci_ce_deinit
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
hif_ce_pipe_info
*
pipe_info
;
struct
ath10k_pci_pipe
*
pipe_info
;
int
pipe_num
;
for
(
pipe_num
=
0
;
pipe_num
<
ar_pci
->
ce_count
;
pipe_num
++
)
{
...
...
@@ -1293,8 +1403,10 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
void
*
resp
,
u32
*
resp_len
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ce_state
*
ce_tx
=
ar_pci
->
pipe_info
[
BMI_CE_NUM_TO_TARG
].
ce_hdl
;
struct
ce_state
*
ce_rx
=
ar_pci
->
pipe_info
[
BMI_CE_NUM_TO_HOST
].
ce_hdl
;
struct
ath10k_pci_pipe
*
pci_tx
=
&
ar_pci
->
pipe_info
[
BMI_CE_NUM_TO_TARG
];
struct
ath10k_pci_pipe
*
pci_rx
=
&
ar_pci
->
pipe_info
[
BMI_CE_NUM_TO_HOST
];
struct
ath10k_ce_pipe
*
ce_tx
=
pci_tx
->
ce_hdl
;
struct
ath10k_ce_pipe
*
ce_rx
=
pci_rx
->
ce_hdl
;
dma_addr_t
req_paddr
=
0
;
dma_addr_t
resp_paddr
=
0
;
struct
bmi_xfer
xfer
=
{};
...
...
@@ -1378,7 +1490,7 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
return
ret
;
}
static
void
ath10k_pci_bmi_send_done
(
struct
ce_stat
e
*
ce_state
,
static
void
ath10k_pci_bmi_send_done
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
data
,
unsigned
int
nbytes
,
...
...
@@ -1392,7 +1504,7 @@ static void ath10k_pci_bmi_send_done(struct ce_state *ce_state,
complete
(
&
xfer
->
done
);
}
static
void
ath10k_pci_bmi_recv_data
(
struct
ce_stat
e
*
ce_state
,
static
void
ath10k_pci_bmi_recv_data
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
data
,
unsigned
int
nbytes
,
...
...
@@ -1679,7 +1791,7 @@ static int ath10k_pci_init_config(struct ath10k *ar)
static
int
ath10k_pci_ce_init
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
hif_ce_pipe_info
*
pipe_info
;
struct
ath10k_pci_pipe
*
pipe_info
;
const
struct
ce_attr
*
attr
;
int
pipe_num
;
...
...
@@ -1895,7 +2007,7 @@ static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
static
void
ath10k_pci_ce_tasklet
(
unsigned
long
ptr
)
{
struct
hif_ce_pipe_info
*
pipe
=
(
struct
hif_ce_pipe_info
*
)
ptr
;
struct
ath10k_pci_pipe
*
pipe
=
(
struct
ath10k_pci_pipe
*
)
ptr
;
struct
ath10k_pci
*
ar_pci
=
pipe
->
ar_pci
;
ath10k_ce_per_engine_service
(
ar_pci
->
ar
,
pipe
->
pipe_num
);
...
...
@@ -2212,18 +2324,13 @@ static int ath10k_pci_reset_target(struct ath10k *ar)
static
void
ath10k_pci_device_reset
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
void
__iomem
*
mem
=
ar_pci
->
mem
;
int
i
;
u32
val
;
if
(
!
SOC_GLOBAL_RESET_ADDRESS
)
return
;
if
(
!
mem
)
return
;
ath10k_pci_reg_write32
(
mem
,
PCIE_SOC_WAKE_ADDRESS
,
ath10k_pci_reg_write32
(
ar
,
PCIE_SOC_WAKE_ADDRESS
,
PCIE_SOC_WAKE_V_MASK
);
for
(
i
=
0
;
i
<
ATH_PCI_RESET_WAIT_MAX
;
i
++
)
{
if
(
ath10k_pci_target_is_awake
(
ar
))
...
...
@@ -2232,12 +2339,12 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
}
/* Put Target, including PCIe, into RESET. */
val
=
ath10k_pci_reg_read32
(
mem
,
SOC_GLOBAL_RESET_ADDRESS
);
val
=
ath10k_pci_reg_read32
(
ar
,
SOC_GLOBAL_RESET_ADDRESS
);
val
|=
1
;
ath10k_pci_reg_write32
(
mem
,
SOC_GLOBAL_RESET_ADDRESS
,
val
);
ath10k_pci_reg_write32
(
ar
,
SOC_GLOBAL_RESET_ADDRESS
,
val
);
for
(
i
=
0
;
i
<
ATH_PCI_RESET_WAIT_MAX
;
i
++
)
{
if
(
ath10k_pci_reg_read32
(
mem
,
RTC_STATE_ADDRESS
)
&
if
(
ath10k_pci_reg_read32
(
ar
,
RTC_STATE_ADDRESS
)
&
RTC_STATE_COLD_RESET_MASK
)
break
;
msleep
(
1
);
...
...
@@ -2245,16 +2352,16 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
/* Pull Target, including PCIe, out of RESET. */
val
&=
~
1
;
ath10k_pci_reg_write32
(
mem
,
SOC_GLOBAL_RESET_ADDRESS
,
val
);
ath10k_pci_reg_write32
(
ar
,
SOC_GLOBAL_RESET_ADDRESS
,
val
);
for
(
i
=
0
;
i
<
ATH_PCI_RESET_WAIT_MAX
;
i
++
)
{
if
(
!
(
ath10k_pci_reg_read32
(
mem
,
RTC_STATE_ADDRESS
)
&
if
(
!
(
ath10k_pci_reg_read32
(
ar
,
RTC_STATE_ADDRESS
)
&
RTC_STATE_COLD_RESET_MASK
))
break
;
msleep
(
1
);
}
ath10k_pci_reg_write32
(
mem
,
PCIE_SOC_WAKE_ADDRESS
,
PCIE_SOC_WAKE_RESET
);
ath10k_pci_reg_write32
(
ar
,
PCIE_SOC_WAKE_ADDRESS
,
PCIE_SOC_WAKE_RESET
);
}
static
void
ath10k_pci_dump_features
(
struct
ath10k_pci
*
ar_pci
)
...
...
@@ -2269,9 +2376,6 @@ static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
case
ATH10K_PCI_FEATURE_MSI_X
:
ath10k_dbg
(
ATH10K_DBG_PCI
,
"device supports MSI-X
\n
"
);
break
;
case
ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND
:
ath10k_dbg
(
ATH10K_DBG_PCI
,
"QCA988X_1.0 workaround enabled
\n
"
);
break
;
case
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
:
ath10k_dbg
(
ATH10K_DBG_PCI
,
"QCA98XX SoC power save enabled
\n
"
);
break
;
...
...
@@ -2286,7 +2390,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
int
ret
=
0
;
struct
ath10k
*
ar
;
struct
ath10k_pci
*
ar_pci
;
u32
lcr_val
;
u32
lcr_val
,
chip_id
;
ath10k_dbg
(
ATH10K_DBG_PCI
,
"%s
\n
"
,
__func__
);
...
...
@@ -2298,9 +2402,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
ar_pci
->
dev
=
&
pdev
->
dev
;
switch
(
pci_dev
->
device
)
{
case
QCA988X_1_0_DEVICE_ID
:
set_bit
(
ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND
,
ar_pci
->
features
);
break
;
case
QCA988X_2_0_DEVICE_ID
:
set_bit
(
ATH10K_PCI_FEATURE_MSI_X
,
ar_pci
->
features
);
break
;
...
...
@@ -2322,10 +2423,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
goto
err_ar_pci
;
}
/* Enable QCA988X_1.0 HW workarounds */
if
(
test_bit
(
ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND
,
ar_pci
->
features
))
spin_lock_init
(
&
ar_pci
->
hw_v1_workaround_lock
);
ar_pci
->
ar
=
ar
;
ar_pci
->
fw_indicator_address
=
FW_INDICATOR_ADDRESS
;
atomic_set
(
&
ar_pci
->
keep_awake_count
,
0
);
...
...
@@ -2395,9 +2492,18 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
spin_lock_init
(
&
ar_pci
->
ce_lock
);
ar_pci
->
cacheline_sz
=
dma_get_cache_alignment
();
ret
=
ath10k_do_pci_wake
(
ar
);
if
(
ret
)
{
ath10k_err
(
"Failed to get chip id: %d
\n
"
,
ret
);
return
ret
;
}
chip_id
=
ath10k_pci_read32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_CHIP_ID_ADDRESS
);
ath10k_do_pci_sleep
(
ar
);
ret
=
ath10k_core_register
(
ar
);
ret
=
ath10k_core_register
(
ar
,
chip_id
);
if
(
ret
)
{
ath10k_err
(
"could not register driver core (%d)
\n
"
,
ret
);
goto
err_iomap
;
...
...
@@ -2483,9 +2589,6 @@ module_exit(ath10k_pci_exit);
MODULE_AUTHOR
(
"Qualcomm Atheros"
);
MODULE_DESCRIPTION
(
"Driver support for Atheros QCA988X PCIe devices"
);
MODULE_LICENSE
(
"Dual BSD/GPL"
);
MODULE_FIRMWARE
(
QCA988X_HW_1_0_FW_DIR
"/"
QCA988X_HW_1_0_FW_FILE
);
MODULE_FIRMWARE
(
QCA988X_HW_1_0_FW_DIR
"/"
QCA988X_HW_1_0_OTP_FILE
);
MODULE_FIRMWARE
(
QCA988X_HW_1_0_FW_DIR
"/"
QCA988X_HW_1_0_BOARD_DATA_FILE
);
MODULE_FIRMWARE
(
QCA988X_HW_2_0_FW_DIR
"/"
QCA988X_HW_2_0_FW_FILE
);
MODULE_FIRMWARE
(
QCA988X_HW_2_0_FW_DIR
"/"
QCA988X_HW_2_0_OTP_FILE
);
MODULE_FIRMWARE
(
QCA988X_HW_2_0_FW_DIR
"/"
QCA988X_HW_2_0_BOARD_DATA_FILE
);
drivers/net/wireless/ath/ath10k/pci.h
浏览文件 @
98497bb2
...
...
@@ -43,22 +43,23 @@ struct bmi_xfer {
u32
resp_len
;
};
enum
ath10k_pci_compl_state
{
ATH10K_PCI_COMPL_FREE
=
0
,
ATH10K_PCI_COMPL_SEND
,
ATH10K_PCI_COMPL_RECV
,
};
struct
ath10k_pci_compl
{
struct
list_head
list
;
int
send_or_recv
;
struct
ce_stat
e
*
ce_state
;
struct
hif_ce_pipe_info
*
pipe_info
;
void
*
transfer_context
;
enum
ath10k_pci_compl_state
state
;
struct
ath10k_ce_pip
e
*
ce_state
;
struct
ath10k_pci_pipe
*
pipe_info
;
struct
sk_buff
*
skb
;
unsigned
int
nbytes
;
unsigned
int
transfer_id
;
unsigned
int
flags
;
};
/* compl_state.send_or_recv */
#define HIF_CE_COMPLETE_FREE 0
#define HIF_CE_COMPLETE_SEND 1
#define HIF_CE_COMPLETE_RECV 2
/*
* PCI-specific Target state
*
...
...
@@ -152,17 +153,16 @@ struct service_to_pipe {
enum
ath10k_pci_features
{
ATH10K_PCI_FEATURE_MSI_X
=
0
,
ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND
=
1
,
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
=
2
,
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
=
1
,
/* keep last */
ATH10K_PCI_FEATURE_COUNT
};
/* Per-pipe state. */
struct
hif_ce_pipe_info
{
struct
ath10k_pci_pipe
{
/* Handle of underlying Copy Engine */
struct
ce_stat
e
*
ce_hdl
;
struct
ath10k_ce_pip
e
*
ce_hdl
;
/* Our pipe number; facilitiates use of pipe_info ptrs. */
u8
pipe_num
;
...
...
@@ -190,7 +190,6 @@ struct ath10k_pci {
struct
device
*
dev
;
struct
ath10k
*
ar
;
void
__iomem
*
mem
;
int
cacheline_sz
;
DECLARE_BITMAP
(
features
,
ATH10K_PCI_FEATURE_COUNT
);
...
...
@@ -219,7 +218,7 @@ struct ath10k_pci {
bool
compl_processing
;
struct
hif_ce_pipe_info
pipe_info
[
CE_COUNT_MAX
];
struct
ath10k_pci_pipe
pipe_info
[
CE_COUNT_MAX
];
struct
ath10k_hif_cb
msg_callbacks_current
;
...
...
@@ -227,16 +226,13 @@ struct ath10k_pci {
u32
fw_indicator_address
;
/* Copy Engine used for Diagnostic Accesses */
struct
ce_stat
e
*
ce_diag
;
struct
ath10k_ce_pip
e
*
ce_diag
;
/* FIXME: document what this really protects */
spinlock_t
ce_lock
;
/* Map CE id to ce_state */
struct
ce_state
*
ce_id_to_state
[
CE_COUNT_MAX
];
/* makes sure that dummy reads are atomic */
spinlock_t
hw_v1_workaround_lock
;
struct
ath10k_ce_pipe
ce_states
[
CE_COUNT_MAX
];
};
static
inline
struct
ath10k_pci
*
ath10k_pci_priv
(
struct
ath10k
*
ar
)
...
...
@@ -244,14 +240,18 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
return
ar
->
hif
.
priv
;
}
static
inline
u32
ath10k_pci_reg_read32
(
void
__iomem
*
mem
,
u32
addr
)
static
inline
u32
ath10k_pci_reg_read32
(
struct
ath10k
*
ar
,
u32
addr
)
{
return
ioread32
(
mem
+
PCIE_LOCAL_BASE_ADDRESS
+
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
(
void
__iomem
*
mem
,
u32
addr
,
u32
val
)
static
inline
void
ath10k_pci_reg_write32
(
struct
ath10k
*
ar
,
u32
addr
,
u32
val
)
{
iowrite32
(
val
,
mem
+
PCIE_LOCAL_BASE_ADDRESS
+
addr
);
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
iowrite32
(
val
,
ar_pci
->
mem
+
PCIE_LOCAL_BASE_ADDRESS
+
addr
);
}
#define ATH_PCI_RESET_WAIT_MAX 10
/* ms */
...
...
@@ -310,23 +310,8 @@ static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset,
u32
value
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
void
__iomem
*
addr
=
ar_pci
->
mem
;
if
(
test_bit
(
ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND
,
ar_pci
->
features
))
{
unsigned
long
irq_flags
;
spin_lock_irqsave
(
&
ar_pci
->
hw_v1_workaround_lock
,
irq_flags
);
ioread32
(
addr
+
offset
+
4
);
/* 3rd read prior to write */
ioread32
(
addr
+
offset
+
4
);
/* 2nd read prior to write */
ioread32
(
addr
+
offset
+
4
);
/* 1st read prior to write */
iowrite32
(
value
,
addr
+
offset
);
spin_unlock_irqrestore
(
&
ar_pci
->
hw_v1_workaround_lock
,
irq_flags
);
}
else
{
iowrite32
(
value
,
addr
+
offset
);
}
iowrite32
(
value
,
ar_pci
->
mem
+
offset
);
}
static
inline
u32
ath10k_pci_read32
(
struct
ath10k
*
ar
,
u32
offset
)
...
...
@@ -336,15 +321,17 @@ static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
return
ioread32
(
ar_pci
->
mem
+
offset
);
}
void
ath10k_do_pci_wake
(
struct
ath10k
*
ar
);
int
ath10k_do_pci_wake
(
struct
ath10k
*
ar
);
void
ath10k_do_pci_sleep
(
struct
ath10k
*
ar
);
static
inline
void
ath10k_pci_wake
(
struct
ath10k
*
ar
)
static
inline
int
ath10k_pci_wake
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
if
(
test_bit
(
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
,
ar_pci
->
features
))
ath10k_do_pci_wake
(
ar
);
return
ath10k_do_pci_wake
(
ar
);
return
0
;
}
static
inline
void
ath10k_pci_sleep
(
struct
ath10k
*
ar
)
...
...
drivers/net/wireless/ath/ath10k/wmi.c
浏览文件 @
98497bb2
...
...
@@ -110,6 +110,7 @@ static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
if
(
atomic_add_return
(
1
,
&
ar
->
wmi
.
pending_tx_count
)
>
WMI_MAX_PENDING_TX_COUNT
)
{
/* avoid using up memory when FW hangs */
dev_kfree_skb
(
skb
);
atomic_dec
(
&
ar
->
wmi
.
pending_tx_count
);
return
-
EBUSY
;
}
...
...
@@ -315,7 +316,9 @@ static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band)
static
int
ath10k_wmi_event_mgmt_rx
(
struct
ath10k
*
ar
,
struct
sk_buff
*
skb
)
{
struct
wmi_mgmt_rx_event
*
event
=
(
struct
wmi_mgmt_rx_event
*
)
skb
->
data
;
struct
wmi_mgmt_rx_event_v1
*
ev_v1
;
struct
wmi_mgmt_rx_event_v2
*
ev_v2
;
struct
wmi_mgmt_rx_hdr_v1
*
ev_hdr
;
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
struct
ieee80211_hdr
*
hdr
;
u32
rx_status
;
...
...
@@ -325,13 +328,24 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
u32
rate
;
u32
buf_len
;
u16
fc
;
int
pull_len
;
if
(
test_bit
(
ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX
,
ar
->
fw_features
))
{
ev_v2
=
(
struct
wmi_mgmt_rx_event_v2
*
)
skb
->
data
;
ev_hdr
=
&
ev_v2
->
hdr
.
v1
;
pull_len
=
sizeof
(
*
ev_v2
);
}
else
{
ev_v1
=
(
struct
wmi_mgmt_rx_event_v1
*
)
skb
->
data
;
ev_hdr
=
&
ev_v1
->
hdr
;
pull_len
=
sizeof
(
*
ev_v1
);
}
channel
=
__le32_to_cpu
(
ev
ent
->
hdr
.
channel
);
buf_len
=
__le32_to_cpu
(
ev
ent
->
hdr
.
buf_len
);
rx_status
=
__le32_to_cpu
(
ev
ent
->
hdr
.
status
);
snr
=
__le32_to_cpu
(
ev
ent
->
hdr
.
snr
);
phy_mode
=
__le32_to_cpu
(
ev
ent
->
hdr
.
phy_mode
);
rate
=
__le32_to_cpu
(
ev
ent
->
hdr
.
rate
);
channel
=
__le32_to_cpu
(
ev
_hdr
->
channel
);
buf_len
=
__le32_to_cpu
(
ev
_hdr
->
buf_len
);
rx_status
=
__le32_to_cpu
(
ev
_hdr
->
status
);
snr
=
__le32_to_cpu
(
ev
_hdr
->
snr
);
phy_mode
=
__le32_to_cpu
(
ev
_hdr
->
phy_mode
);
rate
=
__le32_to_cpu
(
ev
_hdr
->
rate
);
memset
(
status
,
0
,
sizeof
(
*
status
));
...
...
@@ -358,7 +372,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
status
->
signal
=
snr
+
ATH10K_DEFAULT_NOISE_FLOOR
;
status
->
rate_idx
=
get_rate_idx
(
rate
,
status
->
band
);
skb_pull
(
skb
,
sizeof
(
event
->
hdr
)
);
skb_pull
(
skb
,
pull_len
);
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
fc
=
le16_to_cpu
(
hdr
->
frame_control
);
...
...
@@ -943,6 +957,9 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
ar
->
phy_capability
=
__le32_to_cpu
(
ev
->
phy_capability
);
ar
->
num_rf_chains
=
__le32_to_cpu
(
ev
->
num_rf_chains
);
if
(
ar
->
fw_version_build
>
636
)
set_bit
(
ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX
,
ar
->
fw_features
);
if
(
ar
->
num_rf_chains
>
WMI_MAX_SPATIAL_STREAM
)
{
ath10k_warn
(
"hardware advertises support for more spatial streams than it should (%d > %d)
\n
"
,
ar
->
num_rf_chains
,
WMI_MAX_SPATIAL_STREAM
);
...
...
drivers/net/wireless/ath/ath10k/wmi.h
浏览文件 @
98497bb2
...
...
@@ -1268,7 +1268,7 @@ struct wmi_scan_event {
* good idea to pass all the fields in the RX status
* descriptor up to the host.
*/
struct
wmi_mgmt_rx_hdr
{
struct
wmi_mgmt_rx_hdr
_v1
{
__le32
channel
;
__le32
snr
;
__le32
rate
;
...
...
@@ -1277,8 +1277,18 @@ struct wmi_mgmt_rx_hdr {
__le32
status
;
/* %WMI_RX_STATUS_ */
}
__packed
;
struct
wmi_mgmt_rx_event
{
struct
wmi_mgmt_rx_hdr
hdr
;
struct
wmi_mgmt_rx_hdr_v2
{
struct
wmi_mgmt_rx_hdr_v1
v1
;
__le32
rssi_ctl
[
4
];
}
__packed
;
struct
wmi_mgmt_rx_event_v1
{
struct
wmi_mgmt_rx_hdr_v1
hdr
;
u8
buf
[
0
];
}
__packed
;
struct
wmi_mgmt_rx_event_v2
{
struct
wmi_mgmt_rx_hdr_v2
hdr
;
u8
buf
[
0
];
}
__packed
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录