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
Kirill Smelkov
linux
Commits
1698aca0
Commit
1698aca0
authored
Mar 14, 2014
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linville' of
git://github.com/kvalo/ath
parents
4e3b3bcd
70dd77b4
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
638 additions
and
657 deletions
+638
-657
drivers/net/wireless/ath/ath10k/ce.c
drivers/net/wireless/ath/ath10k/ce.c
+8
-8
drivers/net/wireless/ath/ath10k/ce.h
drivers/net/wireless/ath/ath10k/ce.h
+8
-1
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/core.h
+3
-31
drivers/net/wireless/ath/ath10k/hif.h
drivers/net/wireless/ath/ath10k/hif.h
+15
-10
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/htc.c
+17
-8
drivers/net/wireless/ath/ath10k/htt.h
drivers/net/wireless/ath/ath10k/htt.h
+18
-0
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/htt_rx.c
+176
-60
drivers/net/wireless/ath/ath10k/htt_tx.c
drivers/net/wireless/ath/ath10k/htt_tx.c
+110
-95
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/mac.c
+172
-96
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.c
+82
-307
drivers/net/wireless/ath/ath10k/pci.h
drivers/net/wireless/ath/ath10k/pci.h
+0
-28
drivers/net/wireless/ath/ath10k/txrx.c
drivers/net/wireless/ath/ath10k/txrx.c
+15
-9
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.c
+14
-4
No files found.
drivers/net/wireless/ath/ath10k/ce.c
View file @
1698aca0
...
...
@@ -266,12 +266,12 @@ 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
ath10k_ce_pipe
*
ce_state
,
void
*
per_transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
)
int
ath10k_ce_send_nolock
(
struct
ath10k_ce_pipe
*
ce_state
,
void
*
per_transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
)
{
struct
ath10k
*
ar
=
ce_state
->
ar
;
struct
ath10k_ce_ring
*
src_ring
=
ce_state
->
src_ring
;
...
...
@@ -1067,9 +1067,9 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
*
* For the lack of a better place do the check here.
*/
BUILD_BUG_ON
(
TARGET_NUM_MSDU_DESC
>
BUILD_BUG_ON
(
2
*
TARGET_NUM_MSDU_DESC
>
(
CE_HTT_H2T_MSG_SRC_NENTRIES
-
1
));
BUILD_BUG_ON
(
TARGET_10X_NUM_MSDU_DESC
>
BUILD_BUG_ON
(
2
*
TARGET_10X_NUM_MSDU_DESC
>
(
CE_HTT_H2T_MSG_SRC_NENTRIES
-
1
));
ret
=
ath10k_pci_wake
(
ar
);
...
...
drivers/net/wireless/ath/ath10k/ce.h
View file @
1698aca0
...
...
@@ -23,7 +23,7 @@
/* Maximum number of Copy Engine's supported */
#define CE_COUNT_MAX 8
#define CE_HTT_H2T_MSG_SRC_NENTRIES
2048
#define CE_HTT_H2T_MSG_SRC_NENTRIES
4096
/* Descriptor rings must be aligned to this boundary */
#define CE_DESC_RING_ALIGN 8
...
...
@@ -152,6 +152,13 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
unsigned
int
transfer_id
,
unsigned
int
flags
);
int
ath10k_ce_send_nolock
(
struct
ath10k_ce_pipe
*
ce_state
,
void
*
per_transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
);
void
ath10k_ce_send_cb_register
(
struct
ath10k_ce_pipe
*
ce_state
,
void
(
*
send_cb
)(
struct
ath10k_ce_pipe
*
),
int
disable_interrupts
);
...
...
drivers/net/wireless/ath/ath10k/core.h
View file @
1698aca0
...
...
@@ -62,16 +62,13 @@ struct ath10k;
struct
ath10k_skb_cb
{
dma_addr_t
paddr
;
bool
is_mapped
;
bool
is_aborted
;
u8
vdev_id
;
struct
{
u8
tid
;
bool
is_offchan
;
u8
frag_len
;
u8
pad_len
;
struct
ath10k_htt_txbuf
*
txbuf
;
u32
txbuf_paddr
;
}
__packed
htt
;
struct
{
...
...
@@ -87,32 +84,6 @@ static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb)
return
(
struct
ath10k_skb_cb
*
)
&
IEEE80211_SKB_CB
(
skb
)
->
driver_data
;
}
static
inline
int
ath10k_skb_map
(
struct
device
*
dev
,
struct
sk_buff
*
skb
)
{
if
(
ATH10K_SKB_CB
(
skb
)
->
is_mapped
)
return
-
EINVAL
;
ATH10K_SKB_CB
(
skb
)
->
paddr
=
dma_map_single
(
dev
,
skb
->
data
,
skb
->
len
,
DMA_TO_DEVICE
);
if
(
unlikely
(
dma_mapping_error
(
dev
,
ATH10K_SKB_CB
(
skb
)
->
paddr
)))
return
-
EIO
;
ATH10K_SKB_CB
(
skb
)
->
is_mapped
=
true
;
return
0
;
}
static
inline
int
ath10k_skb_unmap
(
struct
device
*
dev
,
struct
sk_buff
*
skb
)
{
if
(
!
ATH10K_SKB_CB
(
skb
)
->
is_mapped
)
return
-
EINVAL
;
dma_unmap_single
(
dev
,
ATH10K_SKB_CB
(
skb
)
->
paddr
,
skb
->
len
,
DMA_TO_DEVICE
);
ATH10K_SKB_CB
(
skb
)
->
is_mapped
=
false
;
return
0
;
}
static
inline
u32
host_interest_item_address
(
u32
item_offset
)
{
return
QCA988X_HOST_INTEREST_ADDRESS
+
item_offset
;
...
...
@@ -288,6 +259,7 @@ struct ath10k_vif {
u8
fixed_rate
;
u8
fixed_nss
;
u8
force_sgi
;
};
struct
ath10k_vif_iter
{
...
...
drivers/net/wireless/ath/ath10k/hif.h
View file @
1698aca0
...
...
@@ -21,6 +21,14 @@
#include <linux/kernel.h>
#include "core.h"
struct
ath10k_hif_sg_item
{
u16
transfer_id
;
void
*
transfer_context
;
/* NULL = tx completion callback not called */
void
*
vaddr
;
/* for debugging mostly */
u32
paddr
;
u16
len
;
};
struct
ath10k_hif_cb
{
int
(
*
tx_completion
)(
struct
ath10k
*
ar
,
struct
sk_buff
*
wbuf
,
...
...
@@ -31,11 +39,9 @@ struct ath10k_hif_cb {
};
struct
ath10k_hif_ops
{
/* Send the head of a buffer to HIF for transmission to the target. */
int
(
*
send_head
)(
struct
ath10k
*
ar
,
u8
pipe_id
,
unsigned
int
transfer_id
,
unsigned
int
nbytes
,
struct
sk_buff
*
buf
);
/* send a scatter-gather list to the target */
int
(
*
tx_sg
)(
struct
ath10k
*
ar
,
u8
pipe_id
,
struct
ath10k_hif_sg_item
*
items
,
int
n_items
);
/*
* API to handle HIF-specific BMI message exchanges, this API is
...
...
@@ -86,12 +92,11 @@ struct ath10k_hif_ops {
};
static
inline
int
ath10k_hif_send_head
(
struct
ath10k
*
ar
,
u8
pipe_id
,
unsigned
int
transfer_id
,
unsigned
int
nbytes
,
struct
sk_buff
*
buf
)
static
inline
int
ath10k_hif_tx_sg
(
struct
ath10k
*
ar
,
u8
pipe_id
,
struct
ath10k_hif_sg_item
*
items
,
int
n_items
)
{
return
ar
->
hif
.
ops
->
send_head
(
ar
,
pipe_id
,
transfer_id
,
nbytes
,
buf
);
return
ar
->
hif
.
ops
->
tx_sg
(
ar
,
pipe_id
,
items
,
n_items
);
}
static
inline
int
ath10k_hif_exchange_bmi_msg
(
struct
ath10k
*
ar
,
...
...
drivers/net/wireless/ath/ath10k/htc.c
View file @
1698aca0
...
...
@@ -63,7 +63,9 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
static
inline
void
ath10k_htc_restore_tx_skb
(
struct
ath10k_htc
*
htc
,
struct
sk_buff
*
skb
)
{
ath10k_skb_unmap
(
htc
->
ar
->
dev
,
skb
);
struct
ath10k_skb_cb
*
skb_cb
=
ATH10K_SKB_CB
(
skb
);
dma_unmap_single
(
htc
->
ar
->
dev
,
skb_cb
->
paddr
,
skb
->
len
,
DMA_TO_DEVICE
);
skb_pull
(
skb
,
sizeof
(
struct
ath10k_htc_hdr
));
}
...
...
@@ -122,6 +124,9 @@ int ath10k_htc_send(struct ath10k_htc *htc,
struct
sk_buff
*
skb
)
{
struct
ath10k_htc_ep
*
ep
=
&
htc
->
endpoint
[
eid
];
struct
ath10k_skb_cb
*
skb_cb
=
ATH10K_SKB_CB
(
skb
);
struct
ath10k_hif_sg_item
sg_item
;
struct
device
*
dev
=
htc
->
ar
->
dev
;
int
credits
=
0
;
int
ret
;
...
...
@@ -157,19 +162,25 @@ int ath10k_htc_send(struct ath10k_htc *htc,
ath10k_htc_prepare_tx_skb
(
ep
,
skb
);
ret
=
ath10k_skb_map
(
htc
->
ar
->
dev
,
skb
);
skb_cb
->
paddr
=
dma_map_single
(
dev
,
skb
->
data
,
skb
->
len
,
DMA_TO_DEVICE
);
ret
=
dma_mapping_error
(
dev
,
skb_cb
->
paddr
);
if
(
ret
)
goto
err_credits
;
ret
=
ath10k_hif_send_head
(
htc
->
ar
,
ep
->
ul_pipe_id
,
ep
->
eid
,
skb
->
len
,
skb
);
sg_item
.
transfer_id
=
ep
->
eid
;
sg_item
.
transfer_context
=
skb
;
sg_item
.
vaddr
=
skb
->
data
;
sg_item
.
paddr
=
skb_cb
->
paddr
;
sg_item
.
len
=
skb
->
len
;
ret
=
ath10k_hif_tx_sg
(
htc
->
ar
,
ep
->
ul_pipe_id
,
&
sg_item
,
1
);
if
(
ret
)
goto
err_unmap
;
return
0
;
err_unmap:
ath10k_skb_unmap
(
htc
->
ar
->
dev
,
skb
);
dma_unmap_single
(
dev
,
skb_cb
->
paddr
,
skb
->
len
,
DMA_TO_DEVICE
);
err_credits:
if
(
ep
->
tx_credit_flow_enabled
)
{
spin_lock_bh
(
&
htc
->
tx_lock
);
...
...
@@ -191,10 +202,8 @@ static int ath10k_htc_tx_completion_handler(struct ath10k *ar,
struct
ath10k_htc
*
htc
=
&
ar
->
htc
;
struct
ath10k_htc_ep
*
ep
=
&
htc
->
endpoint
[
eid
];
if
(
!
skb
)
{
ath10k_warn
(
"invalid sk_buff completion - NULL pointer. firmware crashed?
\n
"
);
if
(
WARN_ON_ONCE
(
!
skb
))
return
0
;
}
ath10k_htc_notify_tx_completion
(
ep
,
skb
);
/* the skb now belongs to the completion handler */
...
...
drivers/net/wireless/ath/ath10k/htt.h
View file @
1698aca0
...
...
@@ -20,6 +20,7 @@
#include <linux/bug.h>
#include <linux/interrupt.h>
#include <linux/dmapool.h>
#include "htc.h"
#include "rx_desc.h"
...
...
@@ -1181,11 +1182,20 @@ struct htt_rx_info {
u32
info1
;
u32
info2
;
}
rate
;
u32
tsf
;
bool
fcs_err
;
bool
amsdu_more
;
bool
mic_err
;
};
struct
ath10k_htt_txbuf
{
struct
htt_data_tx_desc_frag
frags
[
2
];
struct
ath10k_htc_hdr
htc_hdr
;
struct
htt_cmd_hdr
cmd_hdr
;
struct
htt_data_tx_desc
cmd_tx
;
}
__packed
;
struct
ath10k_htt
{
struct
ath10k
*
ar
;
enum
ath10k_htc_ep_id
eid
;
...
...
@@ -1267,11 +1277,18 @@ struct ath10k_htt {
struct
sk_buff
**
pending_tx
;
unsigned
long
*
used_msdu_ids
;
/* bitmap */
wait_queue_head_t
empty_tx_wq
;
struct
dma_pool
*
tx_pool
;
/* set if host-fw communication goes haywire
* used to avoid further failures */
bool
rx_confused
;
struct
tasklet_struct
rx_replenish_task
;
/* This is used to group tx/rx completions separately and process them
* in batches to reduce cache stalls */
struct
tasklet_struct
txrx_compl_task
;
struct
sk_buff_head
tx_compl_q
;
struct
sk_buff_head
rx_compl_q
;
};
#define RX_HTT_HDR_STATUS_LEN 64
...
...
@@ -1343,4 +1360,5 @@ int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
void
ath10k_htt_tx_free_msdu_id
(
struct
ath10k_htt
*
htt
,
u16
msdu_id
);
int
ath10k_htt_mgmt_tx
(
struct
ath10k_htt
*
htt
,
struct
sk_buff
*
);
int
ath10k_htt_tx
(
struct
ath10k_htt
*
htt
,
struct
sk_buff
*
);
#endif
drivers/net/wireless/ath/ath10k/htt_rx.c
View file @
1698aca0
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath/ath10k/htt_tx.c
View file @
1698aca0
...
...
@@ -109,6 +109,14 @@ int ath10k_htt_tx_attach(struct ath10k_htt *htt)
return
-
ENOMEM
;
}
htt
->
tx_pool
=
dma_pool_create
(
"ath10k htt tx pool"
,
htt
->
ar
->
dev
,
sizeof
(
struct
ath10k_htt_txbuf
),
4
,
0
);
if
(
!
htt
->
tx_pool
)
{
kfree
(
htt
->
used_msdu_ids
);
kfree
(
htt
->
pending_tx
);
return
-
ENOMEM
;
}
return
0
;
}
...
...
@@ -117,9 +125,7 @@ static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt)
struct
htt_tx_done
tx_done
=
{
0
};
int
msdu_id
;
/* No locks needed. Called after communication with the device has
* been stopped. */
spin_lock_bh
(
&
htt
->
tx_lock
);
for
(
msdu_id
=
0
;
msdu_id
<
htt
->
max_num_pending_tx
;
msdu_id
++
)
{
if
(
!
test_bit
(
msdu_id
,
htt
->
used_msdu_ids
))
continue
;
...
...
@@ -132,6 +138,7 @@ static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt)
ath10k_txrx_tx_unref
(
htt
,
&
tx_done
);
}
spin_unlock_bh
(
&
htt
->
tx_lock
);
}
void
ath10k_htt_tx_detach
(
struct
ath10k_htt
*
htt
)
...
...
@@ -139,6 +146,7 @@ void ath10k_htt_tx_detach(struct ath10k_htt *htt)
ath10k_htt_tx_cleanup_pending
(
htt
);
kfree
(
htt
->
pending_tx
);
kfree
(
htt
->
used_msdu_ids
);
dma_pool_destroy
(
htt
->
tx_pool
);
return
;
}
...
...
@@ -334,7 +342,9 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
goto
err_free_msdu_id
;
}
res
=
ath10k_skb_map
(
dev
,
msdu
);
skb_cb
->
paddr
=
dma_map_single
(
dev
,
msdu
->
data
,
msdu
->
len
,
DMA_TO_DEVICE
);
res
=
dma_mapping_error
(
dev
,
skb_cb
->
paddr
);
if
(
res
)
goto
err_free_txdesc
;
...
...
@@ -348,8 +358,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
memcpy
(
cmd
->
mgmt_tx
.
hdr
,
msdu
->
data
,
min_t
(
int
,
msdu
->
len
,
HTT_MGMT_FRM_HDR_DOWNLOAD_LEN
));
skb_cb
->
htt
.
frag_len
=
0
;
skb_cb
->
htt
.
pad_len
=
0
;
skb_cb
->
htt
.
txbuf
=
NULL
;
res
=
ath10k_htc_send
(
&
htt
->
ar
->
htc
,
htt
->
eid
,
txdesc
);
if
(
res
)
...
...
@@ -358,7 +367,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
return
0
;
err_unmap_msdu:
ath10k_skb_unmap
(
dev
,
msdu
);
dma_unmap_single
(
dev
,
skb_cb
->
paddr
,
msdu
->
len
,
DMA_TO_DEVICE
);
err_free_txdesc:
dev_kfree_skb_any
(
txdesc
);
err_free_msdu_id:
...
...
@@ -375,19 +384,19 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
int
ath10k_htt_tx
(
struct
ath10k_htt
*
htt
,
struct
sk_buff
*
msdu
)
{
struct
device
*
dev
=
htt
->
ar
->
dev
;
struct
htt_cmd
*
cmd
;
struct
htt_data_tx_desc_frag
*
tx_frags
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
msdu
->
data
;
struct
ath10k_skb_cb
*
skb_cb
=
ATH10K_SKB_CB
(
msdu
);
struct
sk_buff
*
txdesc
=
NULL
;
bool
use_frags
;
u8
vdev_id
=
ATH10K_SKB_CB
(
msdu
)
->
vdev_id
;
u8
tid
;
int
prefetch_len
,
desc_len
;
int
msdu_id
=
-
1
;
struct
ath10k_hif_sg_item
sg_items
[
2
];
struct
htt_data_tx_desc_frag
*
frags
;
u8
vdev_id
=
skb_cb
->
vdev_id
;
u8
tid
=
skb_cb
->
htt
.
tid
;
int
prefetch_len
;
int
res
;
u8
flags0
;
u16
flags1
;
u8
flags0
=
0
;
u16
msdu_id
,
flags1
=
0
;
dma_addr_t
paddr
;
u32
frags_paddr
;
bool
use_frags
;
res
=
ath10k_htt_tx_inc_pending
(
htt
);
if
(
res
)
...
...
@@ -406,114 +415,120 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
prefetch_len
=
min
(
htt
->
prefetch_len
,
msdu
->
len
);
prefetch_len
=
roundup
(
prefetch_len
,
4
);
desc_len
=
sizeof
(
cmd
->
hdr
)
+
sizeof
(
cmd
->
data_tx
)
+
prefetch_len
;
txdesc
=
ath10k_htc_alloc_skb
(
desc_len
);
if
(
!
txdesc
)
{
res
=
-
ENOMEM
;
goto
err_free_msdu_id
;
}
/* 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. */
use_frags
=
htt
->
target_version_major
<
3
||
!
ieee80211_is_mgmt
(
hdr
->
frame_control
);
if
(
!
IS_ALIGNED
((
unsigned
long
)
txdesc
->
data
,
4
))
{
ath10k_warn
(
"htt alignment check failed. dropping packet.
\n
"
);
res
=
-
EIO
;
goto
err_free_
txdesc
;
}
skb_cb
->
htt
.
txbuf
=
dma_pool_alloc
(
htt
->
tx_pool
,
GFP_ATOMIC
,
&
paddr
);
if
(
!
skb_cb
->
htt
.
txbuf
)
goto
err_free_
msdu_id
;
skb_cb
->
htt
.
txbuf_paddr
=
paddr
;
if
(
use_frags
)
{
skb_cb
->
htt
.
frag_len
=
sizeof
(
*
tx_frags
)
*
2
;
skb_cb
->
htt
.
pad_len
=
(
unsigned
long
)
msdu
->
data
-
round_down
((
unsigned
long
)
msdu
->
data
,
4
);
skb_cb
->
paddr
=
dma_map_single
(
dev
,
msdu
->
data
,
msdu
->
len
,
DMA_TO_DEVICE
);
res
=
dma_mapping_error
(
dev
,
skb_cb
->
paddr
);
if
(
res
)
goto
err_free_txbuf
;
skb_push
(
msdu
,
skb_cb
->
htt
.
frag_len
+
skb_cb
->
htt
.
pad_len
);
}
else
{
skb_cb
->
htt
.
frag_len
=
0
;
skb_cb
->
htt
.
pad_len
=
0
;
}
if
(
likely
(
use_frags
))
{
frags
=
skb_cb
->
htt
.
txbuf
->
frags
;
res
=
ath10k_skb_map
(
dev
,
msdu
);
if
(
res
)
goto
err_pull_txfrag
;
if
(
use_frags
)
{
dma_sync_single_for_cpu
(
dev
,
skb_cb
->
paddr
,
msdu
->
len
,
DMA_TO_DEVICE
);
/* tx fragment list must be terminated with zero-entry */
tx_frags
=
(
struct
htt_data_tx_desc_frag
*
)
msdu
->
data
;
tx_frags
[
0
].
paddr
=
__cpu_to_le32
(
skb_cb
->
paddr
+
skb_cb
->
htt
.
frag_len
+
skb_cb
->
htt
.
pad_len
);
tx_frags
[
0
].
len
=
__cpu_to_le32
(
msdu
->
len
-
skb_cb
->
htt
.
frag_len
-
skb_cb
->
htt
.
pad_len
);
tx_frags
[
1
].
paddr
=
__cpu_to_le32
(
0
);
tx_frags
[
1
].
len
=
__cpu_to_le32
(
0
);
dma_sync_single_for_device
(
dev
,
skb_cb
->
paddr
,
msdu
->
len
,
DMA_TO_DEVICE
);
}
frags
[
0
].
paddr
=
__cpu_to_le32
(
skb_cb
->
paddr
);
frags
[
0
].
len
=
__cpu_to_le32
(
msdu
->
len
);
frags
[
1
].
paddr
=
0
;
frags
[
1
].
len
=
0
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
"tx-msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"tx-msdu: "
,
msdu
->
data
,
msdu
->
len
);
flags0
|=
SM
(
ATH10K_HW_TXRX_NATIVE_WIFI
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
skb_put
(
txdesc
,
desc_len
);
cmd
=
(
struct
htt_cmd
*
)
txdesc
->
data
;
frags_paddr
=
skb_cb
->
htt
.
txbuf_paddr
;
}
else
{
flags0
|=
SM
(
ATH10K_HW_TXRX_MGMT
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
tid
=
ATH10K_SKB_CB
(
msdu
)
->
htt
.
tid
;
frags_paddr
=
skb_cb
->
paddr
;
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt data tx using tid %hhu
\n
"
,
tid
);
/* Normally all commands go through HTC which manages tx credits for
* each endpoint and notifies when tx is completed.
*
* HTT endpoint is creditless so there's no need to care about HTC
* flags. In that case it is trivial to fill the HTC header here.
*
* MSDU transmission is considered completed upon HTT event. This
* implies no relevant resources can be freed until after the event is
* received. That's why HTC tx completion handler itself is ignored by
* setting NULL to transfer_context for all sg items.
*
* There is simply no point in pushing HTT TX_FRM through HTC tx path
* as it's a waste of resources. By bypassing HTC it is possible to
* avoid extra memory allocations, compress data structures and thus
* improve performance. */
skb_cb
->
htt
.
txbuf
->
htc_hdr
.
eid
=
htt
->
eid
;
skb_cb
->
htt
.
txbuf
->
htc_hdr
.
len
=
__cpu_to_le16
(
sizeof
(
skb_cb
->
htt
.
txbuf
->
cmd_hdr
)
+
sizeof
(
skb_cb
->
htt
.
txbuf
->
cmd_tx
)
+
prefetch_len
);
skb_cb
->
htt
.
txbuf
->
htc_hdr
.
flags
=
0
;
flags0
=
0
;
if
(
!
ieee80211_has_protected
(
hdr
->
frame_control
))
flags0
|=
HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT
;
flags0
|=
HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT
;
if
(
use_frags
)
flags0
|=
SM
(
ATH10K_HW_TXRX_NATIVE_WIFI
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
else
flags0
|=
SM
(
ATH10K_HW_TXRX_MGMT
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
flags0
|=
HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT
;
flags1
=
0
;
flags1
|=
SM
((
u16
)
vdev_id
,
HTT_DATA_TX_DESC_FLAGS1_VDEV_ID
);
flags1
|=
SM
((
u16
)
tid
,
HTT_DATA_TX_DESC_FLAGS1_EXT_TID
);
flags1
|=
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD
;
flags1
|=
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD
;
cmd
->
hdr
.
msg_type
=
HTT_H2T_MSG_TYPE_TX_FRM
;
cmd
->
data_tx
.
flags0
=
flags0
;
cmd
->
data_tx
.
flags1
=
__cpu_to_le16
(
flags1
);
cmd
->
data_tx
.
len
=
__cpu_to_le16
(
msdu
->
len
-
skb_cb
->
htt
.
frag_len
-
skb_cb
->
htt
.
pad_len
);
cmd
->
data_tx
.
id
=
__cpu_to_le16
(
msdu_id
);
cmd
->
data_tx
.
frags_paddr
=
__cpu_to_le32
(
skb_cb
->
paddr
);
cmd
->
data_tx
.
peerid
=
__cpu_to_le32
(
HTT_INVALID_PEERID
);
memcpy
(
cmd
->
data_tx
.
prefetch
,
hdr
,
prefetch_len
);
skb_cb
->
htt
.
txbuf
->
cmd_hdr
.
msg_type
=
HTT_H2T_MSG_TYPE_TX_FRM
;
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
flags0
=
flags0
;
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
flags1
=
__cpu_to_le16
(
flags1
);
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
len
=
__cpu_to_le16
(
msdu
->
len
);
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
id
=
__cpu_to_le16
(
msdu_id
);
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
frags_paddr
=
__cpu_to_le32
(
frags_paddr
);
skb_cb
->
htt
.
txbuf
->
cmd_tx
.
peerid
=
__cpu_to_le32
(
HTT_INVALID_PEERID
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu
\n
"
,
flags0
,
flags1
,
msdu
->
len
,
msdu_id
,
frags_paddr
,
(
u32
)
skb_cb
->
paddr
,
vdev_id
,
tid
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt tx msdu: "
,
msdu
->
data
,
msdu
->
len
);
res
=
ath10k_htc_send
(
&
htt
->
ar
->
htc
,
htt
->
eid
,
txdesc
);
sg_items
[
0
].
transfer_id
=
0
;
sg_items
[
0
].
transfer_context
=
NULL
;
sg_items
[
0
].
vaddr
=
&
skb_cb
->
htt
.
txbuf
->
htc_hdr
;
sg_items
[
0
].
paddr
=
skb_cb
->
htt
.
txbuf_paddr
+
sizeof
(
skb_cb
->
htt
.
txbuf
->
frags
);
sg_items
[
0
].
len
=
sizeof
(
skb_cb
->
htt
.
txbuf
->
htc_hdr
)
+
sizeof
(
skb_cb
->
htt
.
txbuf
->
cmd_hdr
)
+
sizeof
(
skb_cb
->
htt
.
txbuf
->
cmd_tx
);
sg_items
[
1
].
transfer_id
=
0
;
sg_items
[
1
].
transfer_context
=
NULL
;
sg_items
[
1
].
vaddr
=
msdu
->
data
;
sg_items
[
1
].
paddr
=
skb_cb
->
paddr
;
sg_items
[
1
].
len
=
prefetch_len
;
res
=
ath10k_hif_tx_sg
(
htt
->
ar
,
htt
->
ar
->
htc
.
endpoint
[
htt
->
eid
].
ul_pipe_id
,
sg_items
,
ARRAY_SIZE
(
sg_items
));
if
(
res
)
goto
err_unmap_msdu
;
return
0
;
err_unmap_msdu:
ath10k_skb_unmap
(
dev
,
msdu
);
err_
pull_txfrag
:
skb_pull
(
msdu
,
skb_cb
->
htt
.
frag_len
+
skb_cb
->
htt
.
pad_len
);
err_free_txdesc:
dev_kfree_skb_any
(
txdesc
);
dma_unmap_single
(
dev
,
skb_cb
->
paddr
,
msdu
->
len
,
DMA_TO_DEVICE
);
err_
free_txbuf
:
dma_pool_free
(
htt
->
tx_pool
,
skb_cb
->
htt
.
txbuf
,
skb_cb
->
htt
.
txbuf_paddr
);
err_free_msdu_id:
spin_lock_bh
(
&
htt
->
tx_lock
);
htt
->
pending_tx
[
msdu_id
]
=
NULL
;
...
...
drivers/net/wireless/ath/ath10k/mac.c
View file @
1698aca0
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath/ath10k/pci.c
View file @
1698aca0
This diff is collapsed.
Click to expand it.
drivers/net/wireless/ath/ath10k/pci.h
View file @
1698aca0
...
...
@@ -43,23 +43,6 @@ 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
;
enum
ath10k_pci_compl_state
state
;
struct
ath10k_ce_pipe
*
ce_state
;
struct
ath10k_pci_pipe
*
pipe_info
;
struct
sk_buff
*
skb
;
unsigned
int
nbytes
;
unsigned
int
transfer_id
;
unsigned
int
flags
;
};
/*
* PCI-specific Target state
*
...
...
@@ -175,9 +158,6 @@ struct ath10k_pci_pipe {
/* protects compl_free and num_send_allowed */
spinlock_t
pipe_lock
;
/* List of free CE completion slots */
struct
list_head
compl_free
;
struct
ath10k_pci
*
ar_pci
;
struct
tasklet_struct
intr
;
};
...
...
@@ -205,14 +185,6 @@ struct ath10k_pci {
atomic_t
keep_awake_count
;
bool
verified_awake
;
/* List of CE completions to be processed */
struct
list_head
compl_process
;
/* protects compl_processing and compl_process */
spinlock_t
compl_lock
;
bool
compl_processing
;
struct
ath10k_pci_pipe
pipe_info
[
CE_COUNT_MAX
];
struct
ath10k_hif_cb
msg_callbacks_current
;
...
...
drivers/net/wireless/ath/ath10k/txrx.c
View file @
1698aca0
...
...
@@ -51,7 +51,8 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
struct
ieee80211_tx_info
*
info
;
struct
ath10k_skb_cb
*
skb_cb
;
struct
sk_buff
*
msdu
;
int
ret
;
lockdep_assert_held
(
&
htt
->
tx_lock
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt tx completion msdu_id %u discard %d no_ack %d
\n
"
,
tx_done
->
msdu_id
,
!!
tx_done
->
discard
,
!!
tx_done
->
no_ack
);
...
...
@@ -65,12 +66,12 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
msdu
=
htt
->
pending_tx
[
tx_done
->
msdu_id
];
skb_cb
=
ATH10K_SKB_CB
(
msdu
);
ret
=
ath10k_skb_unmap
(
dev
,
msdu
);
if
(
ret
)
ath10k_warn
(
"data skb unmap failed (%d)
\n
"
,
ret
);
dma_unmap_single
(
dev
,
skb_cb
->
paddr
,
msdu
->
len
,
DMA_TO_DEVICE
);
if
(
skb_cb
->
htt
.
frag_len
)
skb_pull
(
msdu
,
skb_cb
->
htt
.
frag_len
+
skb_cb
->
htt
.
pad_len
);
if
(
skb_cb
->
htt
.
txbuf
)
dma_pool_free
(
htt
->
tx_pool
,
skb_cb
->
htt
.
txbuf
,
skb_cb
->
htt
.
txbuf_paddr
);
ath10k_report_offchan_tx
(
htt
->
ar
,
msdu
);
...
...
@@ -92,13 +93,11 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
/* we do not own the msdu anymore */
exit:
spin_lock_bh
(
&
htt
->
tx_lock
);
htt
->
pending_tx
[
tx_done
->
msdu_id
]
=
NULL
;
ath10k_htt_tx_free_msdu_id
(
htt
,
tx_done
->
msdu_id
);
__ath10k_htt_tx_dec_pending
(
htt
);
if
(
htt
->
num_pending_tx
==
0
)
wake_up
(
&
htt
->
empty_tx_wq
);
spin_unlock_bh
(
&
htt
->
tx_lock
);
}
static
const
u8
rx_legacy_rate_idx
[]
=
{
...
...
@@ -258,6 +257,12 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
status
->
band
=
ch
->
band
;
status
->
freq
=
ch
->
center_freq
;
if
(
info
->
rate
.
info0
&
HTT_RX_INDICATION_INFO0_END_VALID
)
{
/* TSF available only in 32-bit */
status
->
mactime
=
info
->
tsf
&
0xffffffff
;
status
->
flag
|=
RX_FLAG_MACTIME_END
;
}
ath10k_dbg
(
ATH10K_DBG_DATA
,
"rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i
\n
"
,
info
->
skb
,
...
...
@@ -378,7 +383,8 @@ void ath10k_peer_unmap_event(struct ath10k_htt *htt,
spin_lock_bh
(
&
ar
->
data_lock
);
peer
=
ath10k_peer_find_by_id
(
ar
,
ev
->
peer_id
);
if
(
!
peer
)
{
ath10k_warn
(
"unknown peer id %d
\n
"
,
ev
->
peer_id
);
ath10k_warn
(
"peer-unmap-event: unknown peer id %d
\n
"
,
ev
->
peer_id
);
goto
exit
;
}
...
...
drivers/net/wireless/ath/ath10k/wmi.c
View file @
1698aca0
...
...
@@ -1360,7 +1360,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
struct
wmi_bcn_info
*
bcn_info
;
struct
ath10k_vif
*
arvif
;
struct
sk_buff
*
bcn
;
int
vdev_id
=
0
;
int
ret
,
vdev_id
=
0
;
ath10k_dbg
(
ATH10K_DBG_MGMT
,
"WMI_HOST_SWBA_EVENTID
\n
"
);
...
...
@@ -1435,16 +1435,27 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
ath10k_warn
(
"SWBA overrun on vdev %d
\n
"
,
arvif
->
vdev_id
);
ath10k_skb_unmap
(
ar
->
dev
,
arvif
->
beacon
);
dma_unmap_single
(
arvif
->
ar
->
dev
,
ATH10K_SKB_CB
(
arvif
->
beacon
)
->
paddr
,
arvif
->
beacon
->
len
,
DMA_TO_DEVICE
);
dev_kfree_skb_any
(
arvif
->
beacon
);
}
ath10k_skb_map
(
ar
->
dev
,
bcn
);
ATH10K_SKB_CB
(
bcn
)
->
paddr
=
dma_map_single
(
arvif
->
ar
->
dev
,
bcn
->
data
,
bcn
->
len
,
DMA_TO_DEVICE
);
ret
=
dma_mapping_error
(
arvif
->
ar
->
dev
,
ATH10K_SKB_CB
(
bcn
)
->
paddr
);
if
(
ret
)
{
ath10k_warn
(
"failed to map beacon: %d
\n
"
,
ret
);
goto
skip
;
}
arvif
->
beacon
=
bcn
;
arvif
->
beacon_sent
=
false
;
ath10k_wmi_tx_beacon_nowait
(
arvif
);
skip:
spin_unlock_bh
(
&
ar
->
data_lock
);
}
}
...
...
@@ -3382,7 +3393,6 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
ci
->
max_power
=
ch
->
max_power
;
ci
->
reg_power
=
ch
->
max_reg_power
;
ci
->
antenna_max
=
ch
->
max_antenna_gain
;
ci
->
antenna_max
=
0
;
/* mode & flags share storage */
ci
->
mode
=
ch
->
mode
;
...
...
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