Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
98497bb2
Commit
98497bb2
authored
Sep 26, 2013
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linville' of
git://github.com/kvalo/ath
parents
b75ff5e8
763b8cd3
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
626 additions
and
428 deletions
+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
No files found.
drivers/net/wireless/ath/ath10k/ce.c
View file @
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
);
}
}
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,17 +612,25 @@ 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
;
sbase
=
src_ring
->
shadow_base
;
sdesc
=
CE_SRC_RING_TO_DESC
(
sbase
,
sw_index
);
/* Return data from completed source descriptor */
*
bufferp
=
__le32_to_cpu
(
sdesc
->
addr
);
...
...
@@ -662,20 +648,18 @@ static int ath10k_ce_completed_send_next_nolock(struct ce_state *ce_state,
/* Update sw_index */
sw_index
=
CE_RING_IDX_INCR
(
nentries_mask
,
sw_index
);
src_ring
->
sw_index
=
sw_index
;
ret
=
0
;
}
return
ret
;
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,8 +880,8 @@ 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
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
,
...
...
@@ -900,8 +897,8 @@ 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
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
,
...
...
@@ -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
;
}
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
View file @
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,8 +180,8 @@ 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
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
,
...
...
@@ -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,12 +223,12 @@ 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
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
,
...
...
@@ -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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
98497bb2
...
...
@@ -401,11 +401,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
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
))
{
ath10k_warn
(
"htt alignment check failed. dropping packet.
\n
"
);
...
...
@@ -427,6 +433,11 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
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
;
...
...
@@ -439,11 +450,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if
(
res
)
goto
err
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
"txfrag 0x%llx msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
txfrag
)
->
paddr
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
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
,
"msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"msdu: "
,
msdu
->
data
,
msdu
->
len
);
...
...
@@ -459,6 +473,15 @@ 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
;
/* 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
);
...
...
@@ -468,6 +491,13 @@ 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
;
/* 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
;
...
...
drivers/net/wireless/ath/ath10k/hw.h
View file @
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
View file @
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,7 +1727,9 @@ 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
)
&&
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
View file @
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
View file @
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
View file @
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
;
channel
=
__le32_to_cpu
(
event
->
hdr
.
channel
);
buf_len
=
__le32_to_cpu
(
event
->
hdr
.
buf_len
);
rx_status
=
__le32_to_cpu
(
event
->
hdr
.
status
);
snr
=
__le32_to_cpu
(
event
->
hdr
.
snr
);
phy_mode
=
__le32_to_cpu
(
event
->
hdr
.
phy_mode
);
rate
=
__le32_to_cpu
(
event
->
hdr
.
rate
);
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_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
View file @
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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment