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
559c33d8
Commit
559c33d8
authored
Jan 13, 2014
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linville' of
git://github.com/kvalo/ath
parents
ec665fac
51ab1a0a
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
642 additions
and
23 deletions
+642
-23
drivers/net/wireless/ath/ath10k/Kconfig
drivers/net/wireless/ath/ath10k/Kconfig
+7
-0
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/core.h
+11
-0
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/debug.c
+66
-0
drivers/net/wireless/ath/ath10k/htt.h
drivers/net/wireless/ath/ath10k/htt.h
+1
-0
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/htt_rx.c
+15
-0
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/hw.h
+1
-0
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/mac.c
+358
-16
drivers/net/wireless/ath/ath10k/trace.h
drivers/net/wireless/ath/ath10k/trace.h
+21
-0
drivers/net/wireless/ath/ath10k/txrx.c
drivers/net/wireless/ath/ath10k/txrx.c
+1
-1
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.c
+100
-6
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/ath/ath10k/wmi.h
+61
-0
No files found.
drivers/net/wireless/ath/ath10k/Kconfig
View file @
559c33d8
...
...
@@ -37,3 +37,10 @@ config ATH10K_TRACING
---help---
Select this to ath10k use tracing infrastructure.
config ATH10K_DFS_CERTIFIED
bool "Atheros DFS support for certified platforms"
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
default n
---help---
This option enables DFS support for initiating radiation on
ath10k.
drivers/net/wireless/ath/ath10k/core.h
View file @
559c33d8
...
...
@@ -253,6 +253,9 @@ struct ath10k_vif {
u8
bssid
[
ETH_ALEN
];
}
ibss
;
}
u
;
u8
fixed_rate
;
u8
fixed_nss
;
};
struct
ath10k_vif_iter
{
...
...
@@ -272,6 +275,8 @@ struct ath10k_debug {
struct
delayed_work
htt_stats_dwork
;
struct
ath10k_dfs_stats
dfs_stats
;
struct
ath_dfs_pool_stats
dfs_pool_stats
;
u32
fw_dbglog_mask
;
};
enum
ath10k_state
{
...
...
@@ -306,6 +311,9 @@ enum ath10k_fw_features {
/* firmware support tx frame management over WMI, otherwise it's HTT */
ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX
=
2
,
/* Firmware does not support P2P */
ATH10K_FW_FEATURE_NO_P2P
=
3
,
/* keep last */
ATH10K_FW_FEATURE_COUNT
,
};
...
...
@@ -429,6 +437,9 @@ struct ath10k {
struct
list_head
peers
;
wait_queue_head_t
peer_mapping_wq
;
/* number of created peers; protected by data_lock */
int
num_peers
;
struct
work_struct
offchan_tx_work
;
struct
sk_buff_head
offchan_tx_queue
;
struct
completion
offchan_tx_completed
;
...
...
drivers/net/wireless/ath/ath10k/debug.c
View file @
559c33d8
...
...
@@ -614,6 +614,61 @@ static const struct file_operations fops_htt_stats_mask = {
.
llseek
=
default_llseek
,
};
static
ssize_t
ath10k_read_fw_dbglog
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
unsigned
int
len
;
char
buf
[
32
];
len
=
scnprintf
(
buf
,
sizeof
(
buf
),
"0x%08x
\n
"
,
ar
->
debug
.
fw_dbglog_mask
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
len
);
}
static
ssize_t
ath10k_write_fw_dbglog
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ath10k
*
ar
=
file
->
private_data
;
unsigned
long
mask
;
int
ret
;
ret
=
kstrtoul_from_user
(
user_buf
,
count
,
0
,
&
mask
);
if
(
ret
)
return
ret
;
mutex_lock
(
&
ar
->
conf_mutex
);
ar
->
debug
.
fw_dbglog_mask
=
mask
;
if
(
ar
->
state
==
ATH10K_STATE_ON
)
{
ret
=
ath10k_wmi_dbglog_cfg
(
ar
,
ar
->
debug
.
fw_dbglog_mask
);
if
(
ret
)
{
ath10k_warn
(
"dbglog cfg failed from debugfs: %d
\n
"
,
ret
);
goto
exit
;
}
}
ret
=
count
;
exit:
mutex_unlock
(
&
ar
->
conf_mutex
);
return
ret
;
}
static
const
struct
file_operations
fops_fw_dbglog
=
{
.
read
=
ath10k_read_fw_dbglog
,
.
write
=
ath10k_write_fw_dbglog
,
.
open
=
simple_open
,
.
owner
=
THIS_MODULE
,
.
llseek
=
default_llseek
,
};
int
ath10k_debug_start
(
struct
ath10k
*
ar
)
{
int
ret
;
...
...
@@ -625,6 +680,14 @@ int ath10k_debug_start(struct ath10k *ar)
/* continue normally anyway, this isn't serious */
ath10k_warn
(
"failed to start htt stats workqueue: %d
\n
"
,
ret
);
if
(
ar
->
debug
.
fw_dbglog_mask
)
{
ret
=
ath10k_wmi_dbglog_cfg
(
ar
,
ar
->
debug
.
fw_dbglog_mask
);
if
(
ret
)
/* not serious */
ath10k_warn
(
"failed to enable dbglog during start: %d"
,
ret
);
}
return
0
;
}
...
...
@@ -747,6 +810,9 @@ int ath10k_debug_create(struct ath10k *ar)
debugfs_create_file
(
"htt_stats_mask"
,
S_IRUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_htt_stats_mask
);
debugfs_create_file
(
"fw_dbglog"
,
S_IRUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
&
fops_fw_dbglog
);
if
(
config_enabled
(
CONFIG_ATH10K_DFS_CERTIFIED
))
{
debugfs_create_file
(
"dfs_simulate_radar"
,
S_IWUSR
,
ar
->
debug
.
debugfs_phy
,
ar
,
...
...
drivers/net/wireless/ath/ath10k/htt.h
View file @
559c33d8
...
...
@@ -1183,6 +1183,7 @@ struct htt_rx_info {
}
rate
;
bool
fcs_err
;
bool
amsdu_more
;
bool
mic_err
;
};
struct
ath10k_htt
{
...
...
drivers/net/wireless/ath/ath10k/htt_rx.c
View file @
559c33d8
...
...
@@ -838,6 +838,20 @@ static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
return
false
;
}
static
bool
ath10k_htt_rx_has_mic_err
(
struct
sk_buff
*
skb
)
{
struct
htt_rx_desc
*
rxd
;
u32
flags
;
rxd
=
(
void
*
)
skb
->
data
-
sizeof
(
*
rxd
);
flags
=
__le32_to_cpu
(
rxd
->
attention
.
flags
);
if
(
flags
&
RX_ATTENTION_FLAGS_TKIP_MIC_ERR
)
return
true
;
return
false
;
}
static
int
ath10k_htt_rx_get_csum_state
(
struct
sk_buff
*
skb
)
{
struct
htt_rx_desc
*
rxd
;
...
...
@@ -960,6 +974,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
info
.
skb
=
msdu_head
;
info
.
fcs_err
=
ath10k_htt_rx_has_fcs_err
(
msdu_head
);
info
.
mic_err
=
ath10k_htt_rx_has_mic_err
(
msdu_head
);
info
.
signal
=
ATH10K_DEFAULT_NOISE_FLOOR
;
info
.
signal
+=
rx
->
ppdu
.
combined_rssi
;
...
...
drivers/net/wireless/ath/ath10k/hw.h
View file @
559c33d8
...
...
@@ -115,6 +115,7 @@ enum ath10k_mcast2ucast_mode {
#define TARGET_10X_MAC_AGGR_DELIM 0
#define TARGET_10X_AST_SKID_LIMIT 16
#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS))
#define TARGET_10X_NUM_PEERS_MAX 128
#define TARGET_10X_NUM_OFFLOAD_PEERS 0
#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0
#define TARGET_10X_NUM_PEER_KEYS 2
...
...
drivers/net/wireless/ath/ath10k/mac.c
View file @
559c33d8
...
...
@@ -332,6 +332,9 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
ath10k_warn
(
"Failed to wait for created wmi peer: %i
\n
"
,
ret
);
return
ret
;
}
spin_lock_bh
(
&
ar
->
data_lock
);
ar
->
num_peers
++
;
spin_unlock_bh
(
&
ar
->
data_lock
);
return
0
;
}
...
...
@@ -377,6 +380,10 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
if
(
ret
)
return
ret
;
spin_lock_bh
(
&
ar
->
data_lock
);
ar
->
num_peers
--
;
spin_unlock_bh
(
&
ar
->
data_lock
);
return
0
;
}
...
...
@@ -396,6 +403,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
list_del
(
&
peer
->
list
);
kfree
(
peer
);
ar
->
num_peers
--
;
}
spin_unlock_bh
(
&
ar
->
data_lock
);
}
...
...
@@ -411,6 +419,7 @@ static void ath10k_peer_cleanup_all(struct ath10k *ar)
list_del
(
&
peer
->
list
);
kfree
(
peer
);
}
ar
->
num_peers
=
0
;
spin_unlock_bh
(
&
ar
->
data_lock
);
}
...
...
@@ -2205,7 +2214,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
enum
wmi_sta_powersave_param
param
;
int
ret
=
0
;
u32
value
;
u32
value
,
param_id
;
int
bit
;
u32
vdev_param
;
...
...
@@ -2297,6 +2306,13 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
ath10k_warn
(
"Failed to create peer for AP: %d
\n
"
,
ret
);
goto
err_vdev_delete
;
}
param_id
=
ar
->
wmi
.
pdev_param
->
sta_kickout_th
;
/* Disable STA KICKOUT functionality in FW */
ret
=
ath10k_wmi_pdev_set_param
(
ar
,
param_id
,
0
);
if
(
ret
)
ath10k_warn
(
"Failed to disable STA KICKOUT
\n
"
);
}
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_STA
)
{
...
...
@@ -2842,6 +2858,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
{
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
int
max_num_peers
;
int
ret
=
0
;
mutex_lock
(
&
ar
->
conf_mutex
);
...
...
@@ -2852,9 +2869,21 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
/*
* New station addition.
*/
if
(
test_bit
(
ATH10K_FW_FEATURE_WMI_10X
,
ar
->
fw_features
))
max_num_peers
=
TARGET_10X_NUM_PEERS_MAX
-
1
;
else
max_num_peers
=
TARGET_NUM_PEERS
;
if
(
ar
->
num_peers
>=
max_num_peers
)
{
ath10k_warn
(
"Number of peers exceeded: peers number %d (max peers %d)
\n
"
,
ar
->
num_peers
,
max_num_peers
);
ret
=
-
ENOBUFS
;
goto
exit
;
}
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac vdev %d peer create %pM (new sta)
\n
"
,
arvif
->
vdev_id
,
sta
->
addr
);
"mac vdev %d peer create %pM (new sta)
num_peers %d
\n
"
,
arvif
->
vdev_id
,
sta
->
addr
,
ar
->
num_peers
);
ret
=
ath10k_peer_create
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
);
if
(
ret
)
...
...
@@ -2904,7 +2933,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
ath10k_warn
(
"Failed to disassociate station: %pM
\n
"
,
sta
->
addr
);
}
exit:
mutex_unlock
(
&
ar
->
conf_mutex
);
return
ret
;
}
...
...
@@ -3310,6 +3339,307 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
return
ret
;
}
/* Helper table for legacy fixed_rate/bitrate_mask */
static
const
u8
cck_ofdm_rate
[]
=
{
/* CCK */
3
,
/* 1Mbps */
2
,
/* 2Mbps */
1
,
/* 5.5Mbps */
0
,
/* 11Mbps */
/* OFDM */
3
,
/* 6Mbps */
7
,
/* 9Mbps */
2
,
/* 12Mbps */
6
,
/* 18Mbps */
1
,
/* 24Mbps */
5
,
/* 36Mbps */
0
,
/* 48Mbps */
4
,
/* 54Mbps */
};
/* Check if only one bit set */
static
int
ath10k_check_single_mask
(
u32
mask
)
{
int
bit
;
bit
=
ffs
(
mask
);
if
(
!
bit
)
return
0
;
mask
&=
~
BIT
(
bit
-
1
);
if
(
mask
)
return
2
;
return
1
;
}
static
bool
ath10k_default_bitrate_mask
(
struct
ath10k
*
ar
,
enum
ieee80211_band
band
,
const
struct
cfg80211_bitrate_mask
*
mask
)
{
u32
legacy
=
0x00ff
;
u8
ht
=
0xff
,
i
;
u16
vht
=
0x3ff
;
switch
(
band
)
{
case
IEEE80211_BAND_2GHZ
:
legacy
=
0x00fff
;
vht
=
0
;
break
;
case
IEEE80211_BAND_5GHZ
:
break
;
default:
return
false
;
}
if
(
mask
->
control
[
band
].
legacy
!=
legacy
)
return
false
;
for
(
i
=
0
;
i
<
ar
->
num_rf_chains
;
i
++
)
if
(
mask
->
control
[
band
].
ht_mcs
[
i
]
!=
ht
)
return
false
;
for
(
i
=
0
;
i
<
ar
->
num_rf_chains
;
i
++
)
if
(
mask
->
control
[
band
].
vht_mcs
[
i
]
!=
vht
)
return
false
;
return
true
;
}
static
bool
ath10k_bitrate_mask_nss
(
const
struct
cfg80211_bitrate_mask
*
mask
,
enum
ieee80211_band
band
,
u8
*
fixed_nss
)
{
int
ht_nss
=
0
,
vht_nss
=
0
,
i
;
/* check legacy */
if
(
ath10k_check_single_mask
(
mask
->
control
[
band
].
legacy
))
return
false
;
/* check HT */
for
(
i
=
0
;
i
<
IEEE80211_HT_MCS_MASK_LEN
;
i
++
)
{
if
(
mask
->
control
[
band
].
ht_mcs
[
i
]
==
0xff
)
continue
;
else
if
(
mask
->
control
[
band
].
ht_mcs
[
i
]
==
0x00
)
break
;
else
return
false
;
}
ht_nss
=
i
;
/* check VHT */
for
(
i
=
0
;
i
<
NL80211_VHT_NSS_MAX
;
i
++
)
{
if
(
mask
->
control
[
band
].
vht_mcs
[
i
]
==
0x03ff
)
continue
;
else
if
(
mask
->
control
[
band
].
vht_mcs
[
i
]
==
0x0000
)
break
;
else
return
false
;
}
vht_nss
=
i
;
if
(
ht_nss
>
0
&&
vht_nss
>
0
)
return
false
;
if
(
ht_nss
)
*
fixed_nss
=
ht_nss
;
else
if
(
vht_nss
)
*
fixed_nss
=
vht_nss
;
else
return
false
;
return
true
;
}
static
bool
ath10k_bitrate_mask_correct
(
const
struct
cfg80211_bitrate_mask
*
mask
,
enum
ieee80211_band
band
,
enum
wmi_rate_preamble
*
preamble
)
{
int
legacy
=
0
,
ht
=
0
,
vht
=
0
,
i
;
*
preamble
=
WMI_RATE_PREAMBLE_OFDM
;
/* check legacy */
legacy
=
ath10k_check_single_mask
(
mask
->
control
[
band
].
legacy
);
if
(
legacy
>
1
)
return
false
;
/* check HT */
for
(
i
=
0
;
i
<
IEEE80211_HT_MCS_MASK_LEN
;
i
++
)
ht
+=
ath10k_check_single_mask
(
mask
->
control
[
band
].
ht_mcs
[
i
]);
if
(
ht
>
1
)
return
false
;
/* check VHT */
for
(
i
=
0
;
i
<
NL80211_VHT_NSS_MAX
;
i
++
)
vht
+=
ath10k_check_single_mask
(
mask
->
control
[
band
].
vht_mcs
[
i
]);
if
(
vht
>
1
)
return
false
;
/* Currently we support only one fixed_rate */
if
((
legacy
+
ht
+
vht
)
!=
1
)
return
false
;
if
(
ht
)
*
preamble
=
WMI_RATE_PREAMBLE_HT
;
else
if
(
vht
)
*
preamble
=
WMI_RATE_PREAMBLE_VHT
;
return
true
;
}
static
bool
ath10k_bitrate_mask_rate
(
const
struct
cfg80211_bitrate_mask
*
mask
,
enum
ieee80211_band
band
,
u8
*
fixed_rate
,
u8
*
fixed_nss
)
{
u8
rate
=
0
,
pream
=
0
,
nss
=
0
,
i
;
enum
wmi_rate_preamble
preamble
;
/* Check if single rate correct */
if
(
!
ath10k_bitrate_mask_correct
(
mask
,
band
,
&
preamble
))
return
false
;
pream
=
preamble
;
switch
(
preamble
)
{
case
WMI_RATE_PREAMBLE_CCK
:
case
WMI_RATE_PREAMBLE_OFDM
:
i
=
ffs
(
mask
->
control
[
band
].
legacy
)
-
1
;
if
(
band
==
IEEE80211_BAND_2GHZ
&&
i
<
4
)
pream
=
WMI_RATE_PREAMBLE_CCK
;
if
(
band
==
IEEE80211_BAND_5GHZ
)
i
+=
4
;
if
(
i
>=
ARRAY_SIZE
(
cck_ofdm_rate
))
return
false
;
rate
=
cck_ofdm_rate
[
i
];
break
;
case
WMI_RATE_PREAMBLE_HT
:
for
(
i
=
0
;
i
<
IEEE80211_HT_MCS_MASK_LEN
;
i
++
)
if
(
mask
->
control
[
band
].
ht_mcs
[
i
])
break
;
if
(
i
==
IEEE80211_HT_MCS_MASK_LEN
)
return
false
;
rate
=
ffs
(
mask
->
control
[
band
].
ht_mcs
[
i
])
-
1
;
nss
=
i
;
break
;
case
WMI_RATE_PREAMBLE_VHT
:
for
(
i
=
0
;
i
<
NL80211_VHT_NSS_MAX
;
i
++
)
if
(
mask
->
control
[
band
].
vht_mcs
[
i
])
break
;
if
(
i
==
NL80211_VHT_NSS_MAX
)
return
false
;
rate
=
ffs
(
mask
->
control
[
band
].
vht_mcs
[
i
])
-
1
;
nss
=
i
;
break
;
}
*
fixed_nss
=
nss
+
1
;
nss
<<=
4
;
pream
<<=
6
;
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x
\n
"
,
pream
,
nss
,
rate
);
*
fixed_rate
=
pream
|
nss
|
rate
;
return
true
;
}
static
bool
ath10k_get_fixed_rate_nss
(
const
struct
cfg80211_bitrate_mask
*
mask
,
enum
ieee80211_band
band
,
u8
*
fixed_rate
,
u8
*
fixed_nss
)
{
/* First check full NSS mask, if we can simply limit NSS */
if
(
ath10k_bitrate_mask_nss
(
mask
,
band
,
fixed_nss
))
return
true
;
/* Next Check single rate is set */
return
ath10k_bitrate_mask_rate
(
mask
,
band
,
fixed_rate
,
fixed_nss
);
}
static
int
ath10k_set_fixed_rate_param
(
struct
ath10k_vif
*
arvif
,
u8
fixed_rate
,
u8
fixed_nss
)
{
struct
ath10k
*
ar
=
arvif
->
ar
;
u32
vdev_param
;
int
ret
=
0
;
mutex_lock
(
&
ar
->
conf_mutex
);
if
(
arvif
->
fixed_rate
==
fixed_rate
&&
arvif
->
fixed_nss
==
fixed_nss
)
goto
exit
;
if
(
fixed_rate
==
WMI_FIXED_RATE_NONE
)
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac disable fixed bitrate mask
\n
"
);
vdev_param
=
ar
->
wmi
.
vdev_param
->
fixed_rate
;
ret
=
ath10k_wmi_vdev_set_param
(
ar
,
arvif
->
vdev_id
,
vdev_param
,
fixed_rate
);
if
(
ret
)
{
ath10k_warn
(
"Could not set fixed_rate param 0x%02x: %d
\n
"
,
fixed_rate
,
ret
);
ret
=
-
EINVAL
;
goto
exit
;
}
arvif
->
fixed_rate
=
fixed_rate
;
vdev_param
=
ar
->
wmi
.
vdev_param
->
nss
;
ret
=
ath10k_wmi_vdev_set_param
(
ar
,
arvif
->
vdev_id
,
vdev_param
,
fixed_nss
);
if
(
ret
)
{
ath10k_warn
(
"Could not set fixed_nss param %d: %d
\n
"
,
fixed_nss
,
ret
);
ret
=
-
EINVAL
;
goto
exit
;
}
arvif
->
fixed_nss
=
fixed_nss
;
exit:
mutex_unlock
(
&
ar
->
conf_mutex
);
return
ret
;
}
static
int
ath10k_set_bitrate_mask
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
const
struct
cfg80211_bitrate_mask
*
mask
)
{
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
struct
ath10k
*
ar
=
arvif
->
ar
;
enum
ieee80211_band
band
=
ar
->
hw
->
conf
.
chandef
.
chan
->
band
;
u8
fixed_rate
=
WMI_FIXED_RATE_NONE
;
u8
fixed_nss
=
ar
->
num_rf_chains
;
if
(
!
ath10k_default_bitrate_mask
(
ar
,
band
,
mask
))
{
if
(
!
ath10k_get_fixed_rate_nss
(
mask
,
band
,
&
fixed_rate
,
&
fixed_nss
))
return
-
EINVAL
;
}
return
ath10k_set_fixed_rate_param
(
arvif
,
fixed_rate
,
fixed_nss
);
}
static
const
struct
ieee80211_ops
ath10k_ops
=
{
.
tx
=
ath10k_tx
,
.
start
=
ath10k_start
,
...
...
@@ -3332,6 +3662,7 @@ static const struct ieee80211_ops ath10k_ops = {
.
tx_last_beacon
=
ath10k_tx_last_beacon
,
.
restart_complete
=
ath10k_restart_complete
,
.
get_survey
=
ath10k_get_survey
,
.
set_bitrate_mask
=
ath10k_set_bitrate_mask
,
#ifdef CONFIG_PM
.
suspend
=
ath10k_suspend
,
.
resume
=
ath10k_resume
,
...
...
@@ -3464,14 +3795,12 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
},
};
#ifdef CONFIG_ATH10K_DFS_CERTIFIED
static
const
struct
ieee80211_iface_limit
ath10k_if_dfs_limits
[]
=
{
static
const
struct
ieee80211_iface_limit
ath10k_10x_if_limits
[]
=
{
{
.
max
=
8
,
.
types
=
BIT
(
NL80211_IFTYPE_AP
)
},
};
#endif
static
const
struct
ieee80211_iface_combination
ath10k_if_comb
[]
=
{
{
...
...
@@ -3481,19 +3810,22 @@ static const struct ieee80211_iface_combination ath10k_if_comb[] = {
.
num_different_channels
=
1
,
.
beacon_int_infra_match
=
true
,
},
#ifdef CONFIG_ATH10K_DFS_CERTIFIED
};
static
const
struct
ieee80211_iface_combination
ath10k_10x_if_comb
[]
=
{
{
.
limits
=
ath10k_
if_dfs
_limits
,
.
n_limits
=
ARRAY_SIZE
(
ath10k_
if_dfs
_limits
),
.
limits
=
ath10k_
10x_if
_limits
,
.
n_limits
=
ARRAY_SIZE
(
ath10k_
10x_if
_limits
),
.
max_interfaces
=
8
,
.
num_different_channels
=
1
,
.
beacon_int_infra_match
=
true
,
#ifdef CONFIG_ATH10K_DFS_CERTIFIED
.
radar_detect_widths
=
BIT
(
NL80211_CHAN_WIDTH_20_NOHT
)
|
BIT
(
NL80211_CHAN_WIDTH_20
)
|
BIT
(
NL80211_CHAN_WIDTH_40
)
|
BIT
(
NL80211_CHAN_WIDTH_80
),
}
#endif
},
};
static
struct
ieee80211_sta_vht_cap
ath10k_create_vht_cap
(
struct
ath10k
*
ar
)
...
...
@@ -3672,9 +4004,12 @@ int ath10k_mac_register(struct ath10k *ar)
ar
->
hw
->
wiphy
->
interface_modes
=
BIT
(
NL80211_IFTYPE_STATION
)
|
BIT
(
NL80211_IFTYPE_ADHOC
)
|
BIT
(
NL80211_IFTYPE_AP
)
|
BIT
(
NL80211_IFTYPE_P2P_CLIENT
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
);
BIT
(
NL80211_IFTYPE_AP
);
if
(
!
test_bit
(
ATH10K_FW_FEATURE_NO_P2P
,
ar
->
fw_features
))
ar
->
hw
->
wiphy
->
interface_modes
|=
BIT
(
NL80211_IFTYPE_P2P_CLIENT
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
);
ar
->
hw
->
flags
=
IEEE80211_HW_SIGNAL_DBM
|
IEEE80211_HW_SUPPORTS_PS
|
...
...
@@ -3717,8 +4052,15 @@ int ath10k_mac_register(struct ath10k *ar)
*/
ar
->
hw
->
queues
=
4
;
ar
->
hw
->
wiphy
->
iface_combinations
=
ath10k_if_comb
;
ar
->
hw
->
wiphy
->
n_iface_combinations
=
ARRAY_SIZE
(
ath10k_if_comb
);
if
(
test_bit
(
ATH10K_FW_FEATURE_WMI_10X
,
ar
->
fw_features
))
{
ar
->
hw
->
wiphy
->
iface_combinations
=
ath10k_10x_if_comb
;
ar
->
hw
->
wiphy
->
n_iface_combinations
=
ARRAY_SIZE
(
ath10k_10x_if_comb
);
}
else
{
ar
->
hw
->
wiphy
->
iface_combinations
=
ath10k_if_comb
;
ar
->
hw
->
wiphy
->
n_iface_combinations
=
ARRAY_SIZE
(
ath10k_if_comb
);
}
ar
->
hw
->
netdev_features
=
NETIF_F_HW_CSUM
;
...
...
drivers/net/wireless/ath/ath10k/trace.h
View file @
559c33d8
...
...
@@ -182,6 +182,27 @@ TRACE_EVENT(ath10k_htt_stats,
)
);
TRACE_EVENT
(
ath10k_wmi_dbglog
,
TP_PROTO
(
void
*
buf
,
size_t
buf_len
),
TP_ARGS
(
buf
,
buf_len
),
TP_STRUCT__entry
(
__field
(
size_t
,
buf_len
)
__dynamic_array
(
u8
,
buf
,
buf_len
)
),
TP_fast_assign
(
__entry
->
buf_len
=
buf_len
;
memcpy
(
__get_dynamic_array
(
buf
),
buf
,
buf_len
);
),
TP_printk
(
"len %zu"
,
__entry
->
buf_len
)
);
#endif
/* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
/* we don't want to use include/trace/events */
...
...
drivers/net/wireless/ath/ath10k/txrx.c
View file @
559c33d8
...
...
@@ -231,7 +231,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
~
IEEE80211_FCTL_PROTECTED
);
}
if
(
info
->
status
==
HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR
)
if
(
info
->
mic_err
)
status
->
flag
|=
RX_FLAG_MMIC_ERROR
;
if
(
info
->
fcs_err
)
...
...
drivers/net/wireless/ath/ath10k/wmi.c
View file @
559c33d8
...
...
@@ -16,6 +16,7 @@
*/
#include <linux/skbuff.h>
#include <linux/ctype.h>
#include "core.h"
#include "htc.h"
...
...
@@ -875,6 +876,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
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_channel
*
ch
;
struct
ieee80211_hdr
*
hdr
;
u32
rx_status
;
u32
channel
;
...
...
@@ -927,7 +929,25 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
if
(
rx_status
&
WMI_RX_STATUS_ERR_MIC
)
status
->
flag
|=
RX_FLAG_MMIC_ERROR
;
status
->
band
=
phy_mode_to_band
(
phy_mode
);
/* HW can Rx CCK rates on 5GHz. In that case phy_mode is set to
* MODE_11B. This means phy_mode is not a reliable source for the band
* of mgmt rx. */
ch
=
ar
->
scan_channel
;
if
(
!
ch
)
ch
=
ar
->
rx_channel
;
if
(
ch
)
{
status
->
band
=
ch
->
band
;
if
(
phy_mode
==
MODE_11B
&&
status
->
band
==
IEEE80211_BAND_5GHZ
)
ath10k_dbg
(
ATH10K_DBG_MGMT
,
"wmi mgmt rx 11b (CCK) on 5GHz
\n
"
);
}
else
{
ath10k_warn
(
"using (unreliable) phy_mode to extract band for mgmt rx
\n
"
);
status
->
band
=
phy_mode_to_band
(
phy_mode
);
}
status
->
freq
=
ieee80211_channel_to_frequency
(
channel
,
status
->
band
);
status
->
signal
=
snr
+
ATH10K_DEFAULT_NOISE_FLOOR
;
status
->
rate_idx
=
get_rate_idx
(
rate
,
status
->
band
);
...
...
@@ -937,7 +957,11 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
fc
=
le16_to_cpu
(
hdr
->
frame_control
);
if
(
fc
&
IEEE80211_FCTL_PROTECTED
)
{
/* FW delivers WEP Shared Auth frame with Protected Bit set and
* encrypted payload. However in case of PMF it delivers decrypted
* frames with Protected Bit set. */
if
(
ieee80211_has_protected
(
hdr
->
frame_control
)
&&
!
ieee80211_is_auth
(
hdr
->
frame_control
))
{
status
->
flag
|=
RX_FLAG_DECRYPTED
|
RX_FLAG_IV_STRIPPED
|
RX_FLAG_MMIC_STRIPPED
;
hdr
->
frame_control
=
__cpu_to_le16
(
fc
&
...
...
@@ -1047,9 +1071,14 @@ static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
ath10k_dbg
(
ATH10K_DBG_WMI
,
"WMI_ECHO_EVENTID
\n
"
);
}
static
void
ath10k_wmi_event_debug_mesg
(
struct
ath10k
*
ar
,
struct
sk_buff
*
skb
)
static
int
ath10k_wmi_event_debug_mesg
(
struct
ath10k
*
ar
,
struct
sk_buff
*
skb
)
{
ath10k_dbg
(
ATH10K_DBG_WMI
,
"WMI_DEBUG_MESG_EVENTID
\n
"
);
ath10k_dbg
(
ATH10K_DBG_WMI
,
"wmi event debug mesg len %d
\n
"
,
skb
->
len
);
trace_ath10k_wmi_dbglog
(
skb
->
data
,
skb
->
len
);
return
0
;
}
static
void
ath10k_wmi_event_update_stats
(
struct
ath10k
*
ar
,
...
...
@@ -1653,9 +1682,37 @@ static void ath10k_wmi_event_profile_match(struct ath10k *ar,
}
static
void
ath10k_wmi_event_debug_print
(
struct
ath10k
*
ar
,
struct
sk_buff
*
skb
)
struct
sk_buff
*
skb
)
{
ath10k_dbg
(
ATH10K_DBG_WMI
,
"WMI_DEBUG_PRINT_EVENTID
\n
"
);
char
buf
[
101
],
c
;
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
buf
)
-
1
;
i
++
)
{
if
(
i
>=
skb
->
len
)
break
;
c
=
skb
->
data
[
i
];
if
(
c
==
'\0'
)
break
;
if
(
isascii
(
c
)
&&
isprint
(
c
))
buf
[
i
]
=
c
;
else
buf
[
i
]
=
'.'
;
}
if
(
i
==
sizeof
(
buf
)
-
1
)
ath10k_warn
(
"wmi debug print truncated: %d
\n
"
,
skb
->
len
);
/* for some reason the debug prints end with \n, remove that */
if
(
skb
->
data
[
i
-
1
]
==
'\n'
)
i
--
;
/* the last byte is always reserved for the null character */
buf
[
i
]
=
'\0'
;
ath10k_dbg
(
ATH10K_DBG_WMI
,
"wmi event debug print '%s'
\n
"
,
buf
);
}
static
void
ath10k_wmi_event_pdev_qvit
(
struct
ath10k
*
ar
,
struct
sk_buff
*
skb
)
...
...
@@ -3445,3 +3502,40 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar,
type
,
delay_ms
);
return
ath10k_wmi_cmd_send
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
force_fw_hang_cmdid
);
}
int
ath10k_wmi_dbglog_cfg
(
struct
ath10k
*
ar
,
u32
module_enable
)
{
struct
wmi_dbglog_cfg_cmd
*
cmd
;
struct
sk_buff
*
skb
;
u32
cfg
;
skb
=
ath10k_wmi_alloc_skb
(
sizeof
(
*
cmd
));
if
(
!
skb
)
return
-
ENOMEM
;
cmd
=
(
struct
wmi_dbglog_cfg_cmd
*
)
skb
->
data
;
if
(
module_enable
)
{
cfg
=
SM
(
ATH10K_DBGLOG_LEVEL_VERBOSE
,
ATH10K_DBGLOG_CFG_LOG_LVL
);
}
else
{
/* set back defaults, all modules with WARN level */
cfg
=
SM
(
ATH10K_DBGLOG_LEVEL_WARN
,
ATH10K_DBGLOG_CFG_LOG_LVL
);
module_enable
=
~
0
;
}
cmd
->
module_enable
=
__cpu_to_le32
(
module_enable
);
cmd
->
module_valid
=
__cpu_to_le32
(
~
0
);
cmd
->
config_enable
=
__cpu_to_le32
(
cfg
);
cmd
->
config_valid
=
__cpu_to_le32
(
ATH10K_DBGLOG_CFG_LOG_LVL_MASK
);
ath10k_dbg
(
ATH10K_DBG_WMI
,
"wmi dbglog cfg modules %08x %08x config %08x %08x
\n
"
,
__le32_to_cpu
(
cmd
->
module_enable
),
__le32_to_cpu
(
cmd
->
module_valid
),
__le32_to_cpu
(
cmd
->
config_enable
),
__le32_to_cpu
(
cmd
->
config_valid
));
return
ath10k_wmi_cmd_send
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
dbglog_cfg_cmdid
);
}
drivers/net/wireless/ath/ath10k/wmi.h
View file @
559c33d8
...
...
@@ -3003,6 +3003,18 @@ struct wmi_vdev_install_key_arg {
const
void
*
key_data
;
};
/*
* vdev fixed rate format:
* - preamble - b7:b6 - see WMI_RATE_PREMABLE_
* - nss - b5:b4 - ss number (0 mean 1ss)
* - rate_mcs - b3:b0 - as below
* CCK: 0 - 11Mbps, 1 - 5,5Mbps, 2 - 2Mbps, 3 - 1Mbps,
* 4 - 11Mbps (s), 5 - 5,5Mbps (s), 6 - 2Mbps (s)
* OFDM: 0 - 48Mbps, 1 - 24Mbps, 2 - 12Mbps, 3 - 6Mbps,
* 4 - 54Mbps, 5 - 36Mbps, 6 - 18Mbps, 7 - 9Mbps
* HT/VHT: MCS index
*/
/* Preamble types to be used with VDEV fixed rate configuration */
enum
wmi_rate_preamble
{
WMI_RATE_PREAMBLE_OFDM
,
...
...
@@ -4090,6 +4102,54 @@ struct wmi_force_fw_hang_cmd {
__le32
delay_ms
;
}
__packed
;
enum
ath10k_dbglog_level
{
ATH10K_DBGLOG_LEVEL_VERBOSE
=
0
,
ATH10K_DBGLOG_LEVEL_INFO
=
1
,
ATH10K_DBGLOG_LEVEL_WARN
=
2
,
ATH10K_DBGLOG_LEVEL_ERR
=
3
,
};
/* VAP ids to enable dbglog */
#define ATH10K_DBGLOG_CFG_VAP_LOG_LSB 0
#define ATH10K_DBGLOG_CFG_VAP_LOG_MASK 0x0000ffff
/* to enable dbglog in the firmware */
#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_LSB 16
#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_MASK 0x00010000
/* timestamp resolution */
#define ATH10K_DBGLOG_CFG_RESOLUTION_LSB 17
#define ATH10K_DBGLOG_CFG_RESOLUTION_MASK 0x000E0000
/* number of queued messages before sending them to the host */
#define ATH10K_DBGLOG_CFG_REPORT_SIZE_LSB 20
#define ATH10K_DBGLOG_CFG_REPORT_SIZE_MASK 0x0ff00000
/*
* Log levels to enable. This defines the minimum level to enable, this is
* not a bitmask. See enum ath10k_dbglog_level for the values.
*/
#define ATH10K_DBGLOG_CFG_LOG_LVL_LSB 28
#define ATH10K_DBGLOG_CFG_LOG_LVL_MASK 0x70000000
/*
* Note: this is a cleaned up version of a struct firmware uses. For
* example, config_valid was hidden inside an array.
*/
struct
wmi_dbglog_cfg_cmd
{
/* bitmask to hold mod id config*/
__le32
module_enable
;
/* see ATH10K_DBGLOG_CFG_ */
__le32
config_enable
;
/* mask of module id bits to be changed */
__le32
module_valid
;
/* mask of config bits to be changed, see ATH10K_DBGLOG_CFG_ */
__le32
config_valid
;
}
__packed
;
#define ATH10K_RTS_MAX 2347
#define ATH10K_FRAGMT_THRESHOLD_MIN 540
#define ATH10K_FRAGMT_THRESHOLD_MAX 2346
...
...
@@ -4167,5 +4227,6 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
int
ath10k_wmi_force_fw_hang
(
struct
ath10k
*
ar
,
enum
wmi_force_fw_hang_type
type
,
u32
delay_ms
);
int
ath10k_wmi_mgmt_tx
(
struct
ath10k
*
ar
,
struct
sk_buff
*
skb
);
int
ath10k_wmi_dbglog_cfg
(
struct
ath10k
*
ar
,
u32
module_enable
);
#endif
/* _WMI_H_ */
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