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
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
Expand all
Hide 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
This diff is collapsed.
Click to expand it.
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,12 +180,12 @@ int ath10k_ce_send(struct ce_state *ce_state,
unsigned
int
transfer_id
,
unsigned
int
flags
);
void
ath10k_ce_send_cb_register
(
struct
ce_stat
e
*
ce_state
,
void
(
*
send_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
),
void
ath10k_ce_send_cb_register
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
(
*
send_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
),
int
disable_interrupts
);
/* Append a simple buffer (address/length) to a sendlist. */
...
...
@@ -215,7 +205,7 @@ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist,
*
* Implemenation note: Pushes multiple buffers with Gather to Source ring.
*/
int
ath10k_ce_sendlist_send
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_sendlist_send
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_send_context
,
struct
ce_sendlist
*
sendlist
,
/* 14 bits */
...
...
@@ -233,17 +223,17 @@ int ath10k_ce_sendlist_send(struct ce_state *ce_state,
*
* Implemenation note: Pushes a buffer to Dest ring.
*/
int
ath10k_ce_recv_buf_enqueue
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_recv_buf_enqueue
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
per_transfer_recv_context
,
u32
buffer
);
void
ath10k_ce_recv_cb_register
(
struct
ce_stat
e
*
ce_state
,
void
(
*
recv_cb
)
(
struct
ce_stat
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
));
void
ath10k_ce_recv_cb_register
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
(
*
recv_cb
)
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
*
transfer_context
,
u32
buffer
,
unsigned
int
nbytes
,
unsigned
int
transfer_id
,
unsigned
int
flags
));
/* recv flags */
/* Data is byte-swapped */
...
...
@@ -253,7 +243,7 @@ void ath10k_ce_recv_cb_register(struct ce_state *ce_state,
* Supply data for the next completed unprocessed receive descriptor.
* Pops buffer from Dest ring.
*/
int
ath10k_ce_completed_recv_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_completed_recv_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
...
...
@@ -263,7 +253,7 @@ int ath10k_ce_completed_recv_next(struct ce_state *ce_state,
* Supply data for the next completed unprocessed send descriptor.
* Pops 1 completed send buffer from Source ring.
*/
int
ath10k_ce_completed_send_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_completed_send_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
...
...
@@ -272,7 +262,7 @@ int ath10k_ce_completed_send_next(struct ce_state *ce_state,
/*==================CE Engine Initialization=======================*/
/* Initialize an instance of a CE */
struct
ce_stat
e
*
ath10k_ce_init
(
struct
ath10k
*
ar
,
struct
ath10k_ce_pip
e
*
ath10k_ce_init
(
struct
ath10k
*
ar
,
unsigned
int
ce_id
,
const
struct
ce_attr
*
attr
);
...
...
@@ -282,7 +272,7 @@ struct ce_state *ath10k_ce_init(struct ath10k *ar,
* receive buffers. Target DMA must be stopped before using
* this API.
*/
int
ath10k_ce_revoke_recv_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_revoke_recv_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
);
...
...
@@ -291,13 +281,13 @@ int ath10k_ce_revoke_recv_next(struct ce_state *ce_state,
* pending sends. Target DMA must be stopped before using
* this API.
*/
int
ath10k_ce_cancel_send_next
(
struct
ce_stat
e
*
ce_state
,
int
ath10k_ce_cancel_send_next
(
struct
ath10k_ce_pip
e
*
ce_state
,
void
**
per_transfer_contextp
,
u32
*
bufferp
,
unsigned
int
*
nbytesp
,
unsigned
int
*
transfer_idp
);
void
ath10k_ce_deinit
(
struct
ce_stat
e
*
ce_state
);
void
ath10k_ce_deinit
(
struct
ath10k_ce_pip
e
*
ce_state
);
/*==================CE Interrupt Handlers====================*/
void
ath10k_ce_per_engine_service_any
(
struct
ath10k
*
ar
);
...
...
@@ -322,9 +312,6 @@ struct ce_attr {
/* CE_ATTR_* values */
unsigned
int
flags
;
/* currently not in use */
unsigned
int
priority
;
/* #entries in source ring - Must be a power of 2 */
unsigned
int
src_nentries
;
...
...
@@ -336,9 +323,6 @@ struct ce_attr {
/* #entries in destination ring - Must be a power of 2 */
unsigned
int
dest_nentries
;
/* Future use */
void
*
reserved
;
};
/*
...
...
drivers/net/wireless/ath/ath10k/core.c
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,10 +401,16 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
goto
err
;
}
txfrag
=
dev_alloc_skb
(
frag_len
);
if
(
!
txfrag
)
{
res
=
-
ENOMEM
;
goto
err
;
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
<
3
||
!
ieee80211_is_mgmt
(
hdr
->
frame_control
))
{
txfrag
=
dev_alloc_skb
(
frag_len
);
if
(
!
txfrag
)
{
res
=
-
ENOMEM
;
goto
err
;
}
}
if
(
!
IS_ALIGNED
((
unsigned
long
)
txdesc
->
data
,
4
))
{
...
...
@@ -427,23 +433,31 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if
(
res
)
goto
err
;
/* tx fragment list must be terminated with zero-entry */
skb_put
(
txfrag
,
frag_len
);
tx_frags
=
(
struct
htt_data_tx_desc_frag
*
)
txfrag
->
data
;
tx_frags
[
0
].
paddr
=
__cpu_to_le32
(
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
tx_frags
[
0
].
len
=
__cpu_to_le32
(
msdu
->
len
);
tx_frags
[
1
].
paddr
=
__cpu_to_le32
(
0
);
tx_frags
[
1
].
len
=
__cpu_to_le32
(
0
);
res
=
ath10k_skb_map
(
dev
,
txfrag
);
if
(
res
)
goto
err
;
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
<
3
||
!
ieee80211_is_mgmt
(
hdr
->
frame_control
))
{
/* tx fragment list must be terminated with zero-entry */
skb_put
(
txfrag
,
frag_len
);
tx_frags
=
(
struct
htt_data_tx_desc_frag
*
)
txfrag
->
data
;
tx_frags
[
0
].
paddr
=
__cpu_to_le32
(
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
tx_frags
[
0
].
len
=
__cpu_to_le32
(
msdu
->
len
);
tx_frags
[
1
].
paddr
=
__cpu_to_le32
(
0
);
tx_frags
[
1
].
len
=
__cpu_to_le32
(
0
);
res
=
ath10k_skb_map
(
dev
,
txfrag
);
if
(
res
)
goto
err
;
ath10k_dbg
(
ATH10K_DBG_HTT
,
"txfrag 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
txfrag
)
->
paddr
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"txfrag: "
,
txfrag
->
data
,
frag_len
);
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
"txfrag 0x%llx msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
txfrag
)
->
paddr
,
ath10k_dbg
(
ATH10K_DBG_HTT
,
"msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"txfrag: "
,
txfrag
->
data
,
frag_len
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"msdu: "
,
msdu
->
data
,
msdu
->
len
);
...
...
@@ -459,8 +473,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
if
(
!
ieee80211_has_protected
(
hdr
->
frame_control
))
flags0
|=
HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT
;
flags0
|=
HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT
;
flags0
|=
SM
(
ATH10K_HW_TXRX_NATIVE_WIFI
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
>=
3
&&
ieee80211_is_mgmt
(
hdr
->
frame_control
))
flags0
|=
SM
(
ATH10K_HW_TXRX_MGMT
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
else
flags0
|=
SM
(
ATH10K_HW_TXRX_NATIVE_WIFI
,
HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE
);
flags1
=
0
;
flags1
|=
SM
((
u16
)
vdev_id
,
HTT_DATA_TX_DESC_FLAGS1_VDEV_ID
);
...
...
@@ -468,7 +491,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
flags1
|=
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD
;
flags1
|=
HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD
;
frags_paddr
=
ATH10K_SKB_CB
(
txfrag
)
->
paddr
;
/* Since HTT 3.0 there is no separate mgmt tx command. However in case
* of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx
* fragment list host driver specifies directly frame pointer. */
if
(
htt
->
target_version_major
>=
3
&&
ieee80211_is_mgmt
(
hdr
->
frame_control
))
frags_paddr
=
ATH10K_SKB_CB
(
msdu
)
->
paddr
;
else
frags_paddr
=
ATH10K_SKB_CB
(
txfrag
)
->
paddr
;
cmd
->
hdr
.
msg_type
=
HTT_H2T_MSG_TYPE_TX_FRM
;
cmd
->
data_tx
.
flags0
=
flags0
;
...
...
drivers/net/wireless/ath/ath10k/hw.h
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,8 +1727,10 @@ static void ath10k_tx(struct ieee80211_hw *hw,
/* we must calculate tid before we apply qos workaround
* as we'd lose the qos control field */
tid
=
HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST
;
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
)
&&
is_unicast_ether_addr
(
ieee80211_get_DA
(
hdr
)))
{
if
(
ieee80211_is_mgmt
(
hdr
->
frame_control
))
{
tid
=
HTT_DATA_TX_EXT_TID_MGMT
;
}
else
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
)
&&
is_unicast_ether_addr
(
ieee80211_get_DA
(
hdr
)))
{
u8
*
qc
=
ieee80211_get_qos_ctl
(
hdr
);
tid
=
qc
[
0
]
&
IEEE80211_QOS_CTL_TID_MASK
;
}
...
...
drivers/net/wireless/ath/ath10k/pci.c
View file @
98497bb2
This diff is collapsed.
Click to expand it.
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
;
if
(
test_bit
(
ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX
,
ar
->
fw_features
))
{
ev_v2
=
(
struct
wmi_mgmt_rx_event_v2
*
)
skb
->
data
;
ev_hdr
=
&
ev_v2
->
hdr
.
v1
;
pull_len
=
sizeof
(
*
ev_v2
);
}
else
{
ev_v1
=
(
struct
wmi_mgmt_rx_event_v1
*
)
skb
->
data
;
ev_hdr
=
&
ev_v1
->
hdr
;
pull_len
=
sizeof
(
*
ev_v1
);
}
channel
=
__le32_to_cpu
(
ev
ent
->
hdr
.
channel
);
buf_len
=
__le32_to_cpu
(
ev
ent
->
hdr
.
buf_len
);
rx_status
=
__le32_to_cpu
(
ev
ent
->
hdr
.
status
);
snr
=
__le32_to_cpu
(
ev
ent
->
hdr
.
snr
);
phy_mode
=
__le32_to_cpu
(
ev
ent
->
hdr
.
phy_mode
);
rate
=
__le32_to_cpu
(
ev
ent
->
hdr
.
rate
);
channel
=
__le32_to_cpu
(
ev
_hdr
->
channel
);
buf_len
=
__le32_to_cpu
(
ev
_hdr
->
buf_len
);
rx_status
=
__le32_to_cpu
(
ev
_hdr
->
status
);
snr
=
__le32_to_cpu
(
ev
_hdr
->
snr
);
phy_mode
=
__le32_to_cpu
(
ev
_hdr
->
phy_mode
);
rate
=
__le32_to_cpu
(
ev
_hdr
->
rate
);
memset
(
status
,
0
,
sizeof
(
*
status
));
...
...
@@ -358,7 +372,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
status
->
signal
=
snr
+
ATH10K_DEFAULT_NOISE_FLOOR
;
status
->
rate_idx
=
get_rate_idx
(
rate
,
status
->
band
);
skb_pull
(
skb
,
sizeof
(
event
->
hdr
)
);
skb_pull
(
skb
,
pull_len
);
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
fc
=
le16_to_cpu
(
hdr
->
frame_control
);
...
...
@@ -943,6 +957,9 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
ar
->
phy_capability
=
__le32_to_cpu
(
ev
->
phy_capability
);
ar
->
num_rf_chains
=
__le32_to_cpu
(
ev
->
num_rf_chains
);
if
(
ar
->
fw_version_build
>
636
)
set_bit
(
ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX
,
ar
->
fw_features
);
if
(
ar
->
num_rf_chains
>
WMI_MAX_SPATIAL_STREAM
)
{
ath10k_warn
(
"hardware advertises support for more spatial streams than it should (%d > %d)
\n
"
,
ar
->
num_rf_chains
,
WMI_MAX_SPATIAL_STREAM
);
...
...
drivers/net/wireless/ath/ath10k/wmi.h
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