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
9e4b4269
Commit
9e4b4269
authored
Feb 24, 2014
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-linville' of
git://github.com/kvalo/ath
parents
161d7855
9797febc
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
895 additions
and
194 deletions
+895
-194
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath.h
+1
-1
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.c
+31
-5
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/core.h
+41
-6
drivers/net/wireless/ath/ath10k/debug.h
drivers/net/wireless/ath/ath10k/debug.h
+1
-1
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/htt_rx.c
+22
-13
drivers/net/wireless/ath/ath10k/htt_tx.c
drivers/net/wireless/ath/ath10k/htt_tx.c
+2
-2
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/hw.h
+6
-0
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/mac.c
+529
-105
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.c
+133
-14
drivers/net/wireless/ath/ath10k/txrx.c
drivers/net/wireless/ath/ath10k/txrx.c
+2
-2
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.c
+87
-31
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/ath/ath10k/wmi.h
+30
-4
drivers/net/wireless/ath/ath6kl/usb.c
drivers/net/wireless/ath/ath6kl/usb.c
+3
-3
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.c
+2
-2
drivers/net/wireless/ath/regd.c
drivers/net/wireless/ath/regd.c
+5
-5
No files found.
drivers/net/wireless/ath/ath.h
View file @
9e4b4269
...
@@ -63,7 +63,7 @@ enum ath_bus_type {
...
@@ -63,7 +63,7 @@ enum ath_bus_type {
};
};
struct
reg_dmn_pair_mapping
{
struct
reg_dmn_pair_mapping
{
u16
reg
DmnEnum
;
u16
reg
_domain
;
u16
reg_5ghz_ctl
;
u16
reg_5ghz_ctl
;
u16
reg_2ghz_ctl
;
u16
reg_2ghz_ctl
;
};
};
...
...
drivers/net/wireless/ath/ath10k/core.c
View file @
9e4b4269
...
@@ -55,8 +55,7 @@ static void ath10k_send_suspend_complete(struct ath10k *ar)
...
@@ -55,8 +55,7 @@ static void ath10k_send_suspend_complete(struct ath10k *ar)
{
{
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot suspend complete
\n
"
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot suspend complete
\n
"
);
ar
->
is_target_paused
=
true
;
complete
(
&
ar
->
target_suspend
);
wake_up
(
&
ar
->
event_queue
);
}
}
static
int
ath10k_init_connect_htc
(
struct
ath10k
*
ar
)
static
int
ath10k_init_connect_htc
(
struct
ath10k
*
ar
)
...
@@ -470,8 +469,12 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
...
@@ -470,8 +469,12 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
if
(
index
==
ie_len
)
if
(
index
==
ie_len
)
break
;
break
;
if
(
data
[
index
]
&
(
1
<<
bit
))
if
(
data
[
index
]
&
(
1
<<
bit
))
{
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"Enabling feature bit: %i
\n
"
,
i
);
__set_bit
(
i
,
ar
->
fw_features
);
__set_bit
(
i
,
ar
->
fw_features
);
}
}
}
ath10k_dbg_dump
(
ATH10K_DBG_BOOT
,
"features"
,
""
,
ath10k_dbg_dump
(
ATH10K_DBG_BOOT
,
"features"
,
""
,
...
@@ -699,6 +702,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
...
@@ -699,6 +702,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
init_completion
(
&
ar
->
scan
.
started
);
init_completion
(
&
ar
->
scan
.
started
);
init_completion
(
&
ar
->
scan
.
completed
);
init_completion
(
&
ar
->
scan
.
completed
);
init_completion
(
&
ar
->
scan
.
on_channel
);
init_completion
(
&
ar
->
scan
.
on_channel
);
init_completion
(
&
ar
->
target_suspend
);
init_completion
(
&
ar
->
install_key_done
);
init_completion
(
&
ar
->
install_key_done
);
init_completion
(
&
ar
->
vdev_setup_done
);
init_completion
(
&
ar
->
vdev_setup_done
);
...
@@ -722,8 +726,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
...
@@ -722,8 +726,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
INIT_WORK
(
&
ar
->
wmi_mgmt_tx_work
,
ath10k_mgmt_over_wmi_tx_work
);
INIT_WORK
(
&
ar
->
wmi_mgmt_tx_work
,
ath10k_mgmt_over_wmi_tx_work
);
skb_queue_head_init
(
&
ar
->
wmi_mgmt_tx_queue
);
skb_queue_head_init
(
&
ar
->
wmi_mgmt_tx_queue
);
init_waitqueue_head
(
&
ar
->
event_queue
);
INIT_WORK
(
&
ar
->
restart_work
,
ath10k_core_restart
);
INIT_WORK
(
&
ar
->
restart_work
,
ath10k_core_restart
);
return
ar
;
return
ar
;
...
@@ -856,10 +858,34 @@ int ath10k_core_start(struct ath10k *ar)
...
@@ -856,10 +858,34 @@ int ath10k_core_start(struct ath10k *ar)
}
}
EXPORT_SYMBOL
(
ath10k_core_start
);
EXPORT_SYMBOL
(
ath10k_core_start
);
int
ath10k_wait_for_suspend
(
struct
ath10k
*
ar
,
u32
suspend_opt
)
{
int
ret
;
reinit_completion
(
&
ar
->
target_suspend
);
ret
=
ath10k_wmi_pdev_suspend_target
(
ar
,
suspend_opt
);
if
(
ret
)
{
ath10k_warn
(
"could not suspend target (%d)
\n
"
,
ret
);
return
ret
;
}
ret
=
wait_for_completion_timeout
(
&
ar
->
target_suspend
,
1
*
HZ
);
if
(
ret
==
0
)
{
ath10k_warn
(
"suspend timed out - target pause event never came
\n
"
);
return
-
ETIMEDOUT
;
}
return
0
;
}
void
ath10k_core_stop
(
struct
ath10k
*
ar
)
void
ath10k_core_stop
(
struct
ath10k
*
ar
)
{
{
lockdep_assert_held
(
&
ar
->
conf_mutex
);
lockdep_assert_held
(
&
ar
->
conf_mutex
);
/* try to suspend target */
ath10k_wait_for_suspend
(
ar
,
WMI_PDEV_SUSPEND_AND_DISABLE_INTR
);
ath10k_debug_stop
(
ar
);
ath10k_debug_stop
(
ar
);
ath10k_htc_stop
(
&
ar
->
htc
);
ath10k_htc_stop
(
&
ar
->
htc
);
ath10k_htt_detach
(
&
ar
->
htt
);
ath10k_htt_detach
(
&
ar
->
htt
);
...
...
drivers/net/wireless/ath/ath10k/core.h
View file @
9e4b4269
...
@@ -46,6 +46,18 @@
...
@@ -46,6 +46,18 @@
#define ATH10K_MAX_NUM_MGMT_PENDING 128
#define ATH10K_MAX_NUM_MGMT_PENDING 128
/* number of failed packets */
#define ATH10K_KICKOUT_THRESHOLD 50
/*
* Use insanely high numbers to make sure that the firmware implementation
* won't start, we have the same functionality already in hostapd. Unit
* is seconds.
*/
#define ATH10K_KEEPALIVE_MIN_IDLE 3747
#define ATH10K_KEEPALIVE_MAX_IDLE 3895
#define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900
struct
ath10k
;
struct
ath10k
;
struct
ath10k_skb_cb
{
struct
ath10k_skb_cb
{
...
@@ -61,6 +73,11 @@ struct ath10k_skb_cb {
...
@@ -61,6 +73,11 @@ struct ath10k_skb_cb {
u8
frag_len
;
u8
frag_len
;
u8
pad_len
;
u8
pad_len
;
}
__packed
htt
;
}
__packed
htt
;
struct
{
bool
dtim_zero
;
bool
deliver_cab
;
}
bcn
;
}
__packed
;
}
__packed
;
static
inline
struct
ath10k_skb_cb
*
ATH10K_SKB_CB
(
struct
sk_buff
*
skb
)
static
inline
struct
ath10k_skb_cb
*
ATH10K_SKB_CB
(
struct
sk_buff
*
skb
)
...
@@ -211,6 +228,18 @@ struct ath10k_peer {
...
@@ -211,6 +228,18 @@ struct ath10k_peer {
struct
ieee80211_key_conf
*
keys
[
WMI_MAX_KEY_INDEX
+
1
];
struct
ieee80211_key_conf
*
keys
[
WMI_MAX_KEY_INDEX
+
1
];
};
};
struct
ath10k_sta
{
struct
ath10k_vif
*
arvif
;
/* the following are protected by ar->data_lock */
u32
changed
;
/* IEEE80211_RC_* */
u32
bw
;
u32
nss
;
u32
smps
;
struct
work_struct
update_wk
;
};
#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)
#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)
struct
ath10k_vif
{
struct
ath10k_vif
{
...
@@ -222,10 +251,17 @@ struct ath10k_vif {
...
@@ -222,10 +251,17 @@ struct ath10k_vif {
u32
beacon_interval
;
u32
beacon_interval
;
u32
dtim_period
;
u32
dtim_period
;
struct
sk_buff
*
beacon
;
struct
sk_buff
*
beacon
;
/* protected by data_lock */
bool
beacon_sent
;
struct
ath10k
*
ar
;
struct
ath10k
*
ar
;
struct
ieee80211_vif
*
vif
;
struct
ieee80211_vif
*
vif
;
bool
is_started
;
bool
is_up
;
u32
aid
;
u8
bssid
[
ETH_ALEN
];
struct
work_struct
wep_key_work
;
struct
work_struct
wep_key_work
;
struct
ieee80211_key_conf
*
wep_keys
[
WMI_MAX_KEY_INDEX
+
1
];
struct
ieee80211_key_conf
*
wep_keys
[
WMI_MAX_KEY_INDEX
+
1
];
u8
def_wep_key_idx
;
u8
def_wep_key_idx
;
...
@@ -235,7 +271,6 @@ struct ath10k_vif {
...
@@ -235,7 +271,6 @@ struct ath10k_vif {
union
{
union
{
struct
{
struct
{
u8
bssid
[
ETH_ALEN
];
u32
uapsd
;
u32
uapsd
;
}
sta
;
}
sta
;
struct
{
struct
{
...
@@ -249,9 +284,6 @@ struct ath10k_vif {
...
@@ -249,9 +284,6 @@ struct ath10k_vif {
u32
noa_len
;
u32
noa_len
;
u8
*
noa_data
;
u8
*
noa_data
;
}
ap
;
}
ap
;
struct
{
u8
bssid
[
ETH_ALEN
];
}
ibss
;
}
u
;
}
u
;
u8
fixed_rate
;
u8
fixed_rate
;
...
@@ -355,8 +387,7 @@ struct ath10k {
...
@@ -355,8 +387,7 @@ struct ath10k {
const
struct
ath10k_hif_ops
*
ops
;
const
struct
ath10k_hif_ops
*
ops
;
}
hif
;
}
hif
;
wait_queue_head_t
event_queue
;
struct
completion
target_suspend
;
bool
is_target_paused
;
struct
ath10k_bmi
bmi
;
struct
ath10k_bmi
bmi
;
struct
ath10k_wmi
wmi
;
struct
ath10k_wmi
wmi
;
...
@@ -412,6 +443,9 @@ struct ath10k {
...
@@ -412,6 +443,9 @@ struct ath10k {
/* valid during scan; needed for mgmt rx during scan */
/* valid during scan; needed for mgmt rx during scan */
struct
ieee80211_channel
*
scan_channel
;
struct
ieee80211_channel
*
scan_channel
;
/* current operating channel definition */
struct
cfg80211_chan_def
chandef
;
int
free_vdev_map
;
int
free_vdev_map
;
int
monitor_vdev_id
;
int
monitor_vdev_id
;
bool
monitor_enabled
;
bool
monitor_enabled
;
...
@@ -470,6 +504,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
...
@@ -470,6 +504,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
void
ath10k_core_destroy
(
struct
ath10k
*
ar
);
void
ath10k_core_destroy
(
struct
ath10k
*
ar
);
int
ath10k_core_start
(
struct
ath10k
*
ar
);
int
ath10k_core_start
(
struct
ath10k
*
ar
);
int
ath10k_wait_for_suspend
(
struct
ath10k
*
ar
,
u32
suspend_opt
);
void
ath10k_core_stop
(
struct
ath10k
*
ar
);
void
ath10k_core_stop
(
struct
ath10k
*
ar
);
int
ath10k_core_register
(
struct
ath10k
*
ar
,
u32
chip_id
);
int
ath10k_core_register
(
struct
ath10k
*
ar
,
u32
chip_id
);
void
ath10k_core_unregister
(
struct
ath10k
*
ar
);
void
ath10k_core_unregister
(
struct
ath10k
*
ar
);
...
...
drivers/net/wireless/ath/ath10k/debug.h
View file @
9e4b4269
...
@@ -92,7 +92,7 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
...
@@ -92,7 +92,7 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
#ifdef CONFIG_ATH10K_DEBUG
#ifdef CONFIG_ATH10K_DEBUG
__printf
(
2
,
3
)
void
ath10k_dbg
(
enum
ath10k_debug_mask
mask
,
__printf
(
2
,
3
)
void
ath10k_dbg
(
enum
ath10k_debug_mask
mask
,
const
char
*
fmt
,
...);
const
char
*
fmt
,
...);
void
ath10k_dbg_dump
(
enum
ath10k_debug_mask
mask
,
void
ath10k_dbg_dump
(
enum
ath10k_debug_mask
mask
,
const
char
*
msg
,
const
char
*
prefix
,
const
char
*
msg
,
const
char
*
prefix
,
const
void
*
buf
,
size_t
len
);
const
void
*
buf
,
size_t
len
);
...
...
drivers/net/wireless/ath/ath10k/htt_rx.c
View file @
9e4b4269
...
@@ -324,7 +324,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
...
@@ -324,7 +324,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
msdu
->
len
+
skb_tailroom
(
msdu
),
msdu
->
len
+
skb_tailroom
(
msdu
),
DMA_FROM_DEVICE
);
DMA_FROM_DEVICE
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx: "
,
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx
pop
: "
,
msdu
->
data
,
msdu
->
len
+
skb_tailroom
(
msdu
));
msdu
->
data
,
msdu
->
len
+
skb_tailroom
(
msdu
));
rx_desc
=
(
struct
htt_rx_desc
*
)
msdu
->
data
;
rx_desc
=
(
struct
htt_rx_desc
*
)
msdu
->
data
;
...
@@ -417,8 +417,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
...
@@ -417,8 +417,8 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
next
->
len
+
skb_tailroom
(
next
),
next
->
len
+
skb_tailroom
(
next
),
DMA_FROM_DEVICE
);
DMA_FROM_DEVICE
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt rx: "
,
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
next
->
data
,
"htt rx chained: "
,
next
->
data
,
next
->
len
+
skb_tailroom
(
next
));
next
->
len
+
skb_tailroom
(
next
));
skb_trim
(
next
,
0
);
skb_trim
(
next
,
0
);
...
@@ -430,12 +430,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
...
@@ -430,12 +430,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
msdu_chaining
=
1
;
msdu_chaining
=
1
;
}
}
if
(
msdu_len
>
0
)
{
/* This may suggest FW bug? */
ath10k_warn
(
"htt rx msdu len not consumed (%d)
\n
"
,
msdu_len
);
}
last_msdu
=
__le32_to_cpu
(
rx_desc
->
msdu_end
.
info0
)
&
last_msdu
=
__le32_to_cpu
(
rx_desc
->
msdu_end
.
info0
)
&
RX_MSDU_END_INFO0_LAST_MSDU
;
RX_MSDU_END_INFO0_LAST_MSDU
;
...
@@ -751,7 +745,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
...
@@ -751,7 +745,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
/* This shouldn't happen. If it does than it may be a FW bug. */
/* This shouldn't happen. If it does than it may be a FW bug. */
if
(
skb
->
next
)
{
if
(
skb
->
next
)
{
ath10k_warn
(
"received chained non A-MSDU frame
\n
"
);
ath10k_warn
(
"
htt rx
received chained non A-MSDU frame
\n
"
);
ath10k_htt_rx_free_msdu_chain
(
skb
->
next
);
ath10k_htt_rx_free_msdu_chain
(
skb
->
next
);
skb
->
next
=
NULL
;
skb
->
next
=
NULL
;
}
}
...
@@ -937,6 +931,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
...
@@ -937,6 +931,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
}
}
if
(
ath10k_htt_rx_has_decrypt_err
(
msdu_head
))
{
if
(
ath10k_htt_rx_has_decrypt_err
(
msdu_head
))
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx dropping due to decrypt-err
\n
"
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
continue
;
continue
;
}
}
...
@@ -945,12 +941,14 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
...
@@ -945,12 +941,14 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
/* Skip mgmt frames while we handle this in WMI */
/* Skip mgmt frames while we handle this in WMI */
if
(
status
==
HTT_RX_IND_MPDU_STATUS_MGMT_CTRL
)
{
if
(
status
==
HTT_RX_IND_MPDU_STATUS_MGMT_CTRL
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx mgmt ctrl
\n
"
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
continue
;
continue
;
}
}
if
(
status
!=
HTT_RX_IND_MPDU_STATUS_OK
&&
if
(
status
!=
HTT_RX_IND_MPDU_STATUS_OK
&&
status
!=
HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR
&&
status
!=
HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR
&&
status
!=
HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER
&&
!
htt
->
ar
->
monitor_enabled
)
{
!
htt
->
ar
->
monitor_enabled
)
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx ignoring frame w/ status %d
\n
"
,
"htt rx ignoring frame w/ status %d
\n
"
,
...
@@ -960,6 +958,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
...
@@ -960,6 +958,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
}
}
if
(
test_bit
(
ATH10K_CAC_RUNNING
,
&
htt
->
ar
->
dev_flags
))
{
if
(
test_bit
(
ATH10K_CAC_RUNNING
,
&
htt
->
ar
->
dev_flags
))
{
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx CAC running
\n
"
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
continue
;
continue
;
}
}
...
@@ -967,7 +967,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
...
@@ -967,7 +967,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
/* FIXME: we do not support chaining yet.
/* FIXME: we do not support chaining yet.
* this needs investigation */
* this needs investigation */
if
(
msdu_chaining
)
{
if
(
msdu_chaining
)
{
ath10k_warn
(
"msdu_chaining is true
\n
"
);
ath10k_warn
(
"
htt rx
msdu_chaining is true
\n
"
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
ath10k_htt_rx_free_msdu_chain
(
msdu_head
);
continue
;
continue
;
}
}
...
@@ -975,6 +975,15 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
...
@@ -975,6 +975,15 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
info
.
skb
=
msdu_head
;
info
.
skb
=
msdu_head
;
info
.
fcs_err
=
ath10k_htt_rx_has_fcs_err
(
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
.
mic_err
=
ath10k_htt_rx_has_mic_err
(
msdu_head
);
if
(
info
.
fcs_err
)
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx has FCS err
\n
"
);
if
(
info
.
mic_err
)
ath10k_dbg
(
ATH10K_DBG_HTT
,
"htt rx has MIC err
\n
"
);
info
.
signal
=
ATH10K_DEFAULT_NOISE_FLOOR
;
info
.
signal
=
ATH10K_DEFAULT_NOISE_FLOOR
;
info
.
signal
+=
rx
->
ppdu
.
combined_rssi
;
info
.
signal
+=
rx
->
ppdu
.
combined_rssi
;
...
@@ -1095,7 +1104,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
...
@@ -1095,7 +1104,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
skb_trim
(
info
.
skb
,
info
.
skb
->
len
-
trim
);
skb_trim
(
info
.
skb
,
info
.
skb
->
len
-
trim
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt frag mpdu: "
,
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"htt
rx
frag mpdu: "
,
info
.
skb
->
data
,
info
.
skb
->
len
);
info
.
skb
->
data
,
info
.
skb
->
len
);
ath10k_process_rx
(
htt
->
ar
,
&
info
);
ath10k_process_rx
(
htt
->
ar
,
&
info
);
...
@@ -1116,7 +1125,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
...
@@ -1116,7 +1125,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
if
(
!
IS_ALIGNED
((
unsigned
long
)
skb
->
data
,
4
))
if
(
!
IS_ALIGNED
((
unsigned
long
)
skb
->
data
,
4
))
ath10k_warn
(
"unaligned htt message, expect trouble
\n
"
);
ath10k_warn
(
"unaligned htt message, expect trouble
\n
"
);
ath10k_dbg
(
ATH10K_DBG_HTT
,
"
HTT RX
, msg_type: 0x%0X
\n
"
,
ath10k_dbg
(
ATH10K_DBG_HTT
,
"
htt rx
, msg_type: 0x%0X
\n
"
,
resp
->
hdr
.
msg_type
);
resp
->
hdr
.
msg_type
);
switch
(
resp
->
hdr
.
msg_type
)
{
switch
(
resp
->
hdr
.
msg_type
)
{
case
HTT_T2H_MSG_TYPE_VERSION_CONF
:
{
case
HTT_T2H_MSG_TYPE_VERSION_CONF
:
{
...
...
drivers/net/wireless/ath/ath10k/htt_tx.c
View file @
9e4b4269
...
@@ -460,9 +460,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
...
@@ -460,9 +460,9 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
DMA_TO_DEVICE
);
DMA_TO_DEVICE
);
}
}
ath10k_dbg
(
ATH10K_DBG_HTT
,
"msdu 0x%llx
\n
"
,
ath10k_dbg
(
ATH10K_DBG_HTT
,
"
tx-
msdu 0x%llx
\n
"
,
(
unsigned
long
long
)
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
(
unsigned
long
long
)
ATH10K_SKB_CB
(
msdu
)
->
paddr
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"msdu: "
,
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"
tx-
msdu: "
,
msdu
->
data
,
msdu
->
len
);
msdu
->
data
,
msdu
->
len
);
skb_put
(
txdesc
,
desc_len
);
skb_put
(
txdesc
,
desc_len
);
...
...
drivers/net/wireless/ath/ath10k/hw.h
View file @
9e4b4269
...
@@ -205,8 +205,11 @@ enum ath10k_mcast2ucast_mode {
...
@@ -205,8 +205,11 @@ enum ath10k_mcast2ucast_mode {
#define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000
#define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000
#define PCIE_LOCAL_BASE_ADDRESS 0x00080000
#define PCIE_LOCAL_BASE_ADDRESS 0x00080000
#define SOC_RESET_CONTROL_ADDRESS 0x00000000
#define SOC_RESET_CONTROL_OFFSET 0x00000000
#define SOC_RESET_CONTROL_OFFSET 0x00000000
#define SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001
#define SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001
#define SOC_RESET_CONTROL_CE_RST_MASK 0x00040000
#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
#define SOC_CPU_CLOCK_OFFSET 0x00000020
#define SOC_CPU_CLOCK_OFFSET 0x00000020
#define SOC_CPU_CLOCK_STANDARD_LSB 0
#define SOC_CPU_CLOCK_STANDARD_LSB 0
#define SOC_CPU_CLOCK_STANDARD_MASK 0x00000003
#define SOC_CPU_CLOCK_STANDARD_MASK 0x00000003
...
@@ -216,6 +219,8 @@ enum ath10k_mcast2ucast_mode {
...
@@ -216,6 +219,8 @@ enum ath10k_mcast2ucast_mode {
#define SOC_LPO_CAL_OFFSET 0x000000e0
#define SOC_LPO_CAL_OFFSET 0x000000e0
#define SOC_LPO_CAL_ENABLE_LSB 20
#define SOC_LPO_CAL_ENABLE_LSB 20
#define SOC_LPO_CAL_ENABLE_MASK 0x00100000
#define SOC_LPO_CAL_ENABLE_MASK 0x00100000
#define SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050
#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004
#define SOC_CHIP_ID_ADDRESS 0x000000ec
#define SOC_CHIP_ID_ADDRESS 0x000000ec
#define SOC_CHIP_ID_REV_LSB 8
#define SOC_CHIP_ID_REV_LSB 8
...
@@ -273,6 +278,7 @@ enum ath10k_mcast2ucast_mode {
...
@@ -273,6 +278,7 @@ enum ath10k_mcast2ucast_mode {
#define PCIE_INTR_CAUSE_ADDRESS 0x000c
#define PCIE_INTR_CAUSE_ADDRESS 0x000c
#define PCIE_INTR_CLR_ADDRESS 0x0014
#define PCIE_INTR_CLR_ADDRESS 0x0014
#define SCRATCH_3_ADDRESS 0x0030
#define SCRATCH_3_ADDRESS 0x0030
#define CPU_INTR_ADDRESS 0x0010
/* Firmware indications to the Host via SCRATCH_3 register. */
/* Firmware indications to the Host via SCRATCH_3 register. */
#define FW_INDICATOR_ADDRESS (SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS)
#define FW_INDICATOR_ADDRESS (SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS)
...
...
drivers/net/wireless/ath/ath10k/mac.c
View file @
9e4b4269
...
@@ -339,6 +339,50 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
...
@@ -339,6 +339,50 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
return
0
;
return
0
;
}
}
static
int
ath10k_mac_set_kickout
(
struct
ath10k_vif
*
arvif
)
{
struct
ath10k
*
ar
=
arvif
->
ar
;
u32
param
;
int
ret
;
param
=
ar
->
wmi
.
pdev_param
->
sta_kickout_th
;
ret
=
ath10k_wmi_pdev_set_param
(
ar
,
param
,
ATH10K_KICKOUT_THRESHOLD
);
if
(
ret
)
{
ath10k_warn
(
"Failed to set kickout threshold: %d
\n
"
,
ret
);
return
ret
;
}
param
=
ar
->
wmi
.
vdev_param
->
ap_keepalive_min_idle_inactive_time_secs
;
ret
=
ath10k_wmi_vdev_set_param
(
ar
,
arvif
->
vdev_id
,
param
,
ATH10K_KEEPALIVE_MIN_IDLE
);
if
(
ret
)
{
ath10k_warn
(
"Failed to set keepalive minimum idle time : %d
\n
"
,
ret
);
return
ret
;
}
param
=
ar
->
wmi
.
vdev_param
->
ap_keepalive_max_idle_inactive_time_secs
;
ret
=
ath10k_wmi_vdev_set_param
(
ar
,
arvif
->
vdev_id
,
param
,
ATH10K_KEEPALIVE_MAX_IDLE
);
if
(
ret
)
{
ath10k_warn
(
"Failed to set keepalive maximum idle time: %d
\n
"
,
ret
);
return
ret
;
}
param
=
ar
->
wmi
.
vdev_param
->
ap_keepalive_max_unresponsive_time_secs
;
ret
=
ath10k_wmi_vdev_set_param
(
ar
,
arvif
->
vdev_id
,
param
,
ATH10K_KEEPALIVE_MAX_UNRESPONSIVE
);
if
(
ret
)
{
ath10k_warn
(
"Failed to set keepalive maximum unresponsive time: %d
\n
"
,
ret
);
return
ret
;
}
return
0
;
}
static
int
ath10k_mac_set_rts
(
struct
ath10k_vif
*
arvif
,
u32
value
)
static
int
ath10k_mac_set_rts
(
struct
ath10k_vif
*
arvif
,
u32
value
)
{
{
struct
ath10k
*
ar
=
arvif
->
ar
;
struct
ath10k
*
ar
=
arvif
->
ar
;
...
@@ -444,8 +488,7 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
...
@@ -444,8 +488,7 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
static
int
ath10k_vdev_start
(
struct
ath10k_vif
*
arvif
)
static
int
ath10k_vdev_start
(
struct
ath10k_vif
*
arvif
)
{
{
struct
ath10k
*
ar
=
arvif
->
ar
;
struct
ath10k
*
ar
=
arvif
->
ar
;
struct
ieee80211_conf
*
conf
=
&
ar
->
hw
->
conf
;
struct
cfg80211_chan_def
*
chandef
=
&
ar
->
chandef
;
struct
ieee80211_channel
*
channel
=
conf
->
chandef
.
chan
;
struct
wmi_vdev_start_request_arg
arg
=
{};
struct
wmi_vdev_start_request_arg
arg
=
{};
int
ret
=
0
;
int
ret
=
0
;
...
@@ -457,16 +500,14 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
...
@@ -457,16 +500,14 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
arg
.
dtim_period
=
arvif
->
dtim_period
;
arg
.
dtim_period
=
arvif
->
dtim_period
;
arg
.
bcn_intval
=
arvif
->
beacon_interval
;
arg
.
bcn_intval
=
arvif
->
beacon_interval
;
arg
.
channel
.
freq
=
channel
->
center_freq
;
arg
.
channel
.
freq
=
chandef
->
chan
->
center_freq
;
arg
.
channel
.
band_center_freq1
=
chandef
->
center_freq1
;
arg
.
channel
.
band_center_freq1
=
conf
->
chandef
.
center_freq1
;
arg
.
channel
.
mode
=
chan_to_phymode
(
chandef
);
arg
.
channel
.
mode
=
chan_to_phymode
(
&
conf
->
chandef
);
arg
.
channel
.
min_power
=
0
;
arg
.
channel
.
min_power
=
0
;
arg
.
channel
.
max_power
=
chan
nel
->
max_power
*
2
;
arg
.
channel
.
max_power
=
chan
def
->
chan
->
max_power
*
2
;
arg
.
channel
.
max_reg_power
=
chan
nel
->
max_reg_power
*
2
;
arg
.
channel
.
max_reg_power
=
chan
def
->
chan
->
max_reg_power
*
2
;
arg
.
channel
.
max_antenna_gain
=
chan
nel
->
max_antenna_gain
*
2
;
arg
.
channel
.
max_antenna_gain
=
chan
def
->
chan
->
max_antenna_gain
*
2
;
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_AP
)
{
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_AP
)
{
arg
.
ssid
=
arvif
->
u
.
ap
.
ssid
;
arg
.
ssid
=
arvif
->
u
.
ap
.
ssid
;
...
@@ -475,7 +516,7 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
...
@@ -475,7 +516,7 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
/* For now allow DFS for AP mode */
/* For now allow DFS for AP mode */
arg
.
channel
.
chan_radar
=
arg
.
channel
.
chan_radar
=
!!
(
chan
nel
->
flags
&
IEEE80211_CHAN_RADAR
);
!!
(
chan
def
->
chan
->
flags
&
IEEE80211_CHAN_RADAR
);
}
else
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_IBSS
)
{
}
else
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_IBSS
)
{
arg
.
ssid
=
arvif
->
vif
->
bss_conf
.
ssid
;
arg
.
ssid
=
arvif
->
vif
->
bss_conf
.
ssid
;
arg
.
ssid_len
=
arvif
->
vif
->
bss_conf
.
ssid_len
;
arg
.
ssid_len
=
arvif
->
vif
->
bss_conf
.
ssid_len
;
...
@@ -527,7 +568,8 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
...
@@ -527,7 +568,8 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
static
int
ath10k_monitor_start
(
struct
ath10k
*
ar
,
int
vdev_id
)
static
int
ath10k_monitor_start
(
struct
ath10k
*
ar
,
int
vdev_id
)
{
{
struct
ieee80211_channel
*
channel
=
ar
->
hw
->
conf
.
chandef
.
chan
;
struct
cfg80211_chan_def
*
chandef
=
&
ar
->
chandef
;
struct
ieee80211_channel
*
channel
=
chandef
->
chan
;
struct
wmi_vdev_start_request_arg
arg
=
{};
struct
wmi_vdev_start_request_arg
arg
=
{};
int
ret
=
0
;
int
ret
=
0
;
...
@@ -540,11 +582,11 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
...
@@ -540,11 +582,11 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
arg
.
vdev_id
=
vdev_id
;
arg
.
vdev_id
=
vdev_id
;
arg
.
channel
.
freq
=
channel
->
center_freq
;
arg
.
channel
.
freq
=
channel
->
center_freq
;
arg
.
channel
.
band_center_freq1
=
ar
->
hw
->
conf
.
chandef
.
center_freq1
;
arg
.
channel
.
band_center_freq1
=
chandef
->
center_freq1
;
/* TODO setup this dynamically, what in case we
/* TODO setup this dynamically, what in case we
don't have any vifs? */
don't have any vifs? */
arg
.
channel
.
mode
=
chan_to_phymode
(
&
ar
->
hw
->
conf
.
chandef
);
arg
.
channel
.
mode
=
chan_to_phymode
(
chandef
);
arg
.
channel
.
chan_radar
=
arg
.
channel
.
chan_radar
=
!!
(
channel
->
flags
&
IEEE80211_CHAN_RADAR
);
!!
(
channel
->
flags
&
IEEE80211_CHAN_RADAR
);
...
@@ -791,6 +833,20 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
...
@@ -791,6 +833,20 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
if
(
!
info
->
enable_beacon
)
{
if
(
!
info
->
enable_beacon
)
{
ath10k_vdev_stop
(
arvif
);
ath10k_vdev_stop
(
arvif
);
arvif
->
is_started
=
false
;
arvif
->
is_up
=
false
;
spin_lock_bh
(
&
arvif
->
ar
->
data_lock
);
if
(
arvif
->
beacon
)
{
ath10k_skb_unmap
(
arvif
->
ar
->
dev
,
arvif
->
beacon
);
dev_kfree_skb_any
(
arvif
->
beacon
);
arvif
->
beacon
=
NULL
;
arvif
->
beacon_sent
=
false
;
}
spin_unlock_bh
(
&
arvif
->
ar
->
data_lock
);
return
;
return
;
}
}
...
@@ -800,12 +856,21 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
...
@@ -800,12 +856,21 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
if
(
ret
)
if
(
ret
)
return
;
return
;
ret
=
ath10k_wmi_vdev_up
(
arvif
->
ar
,
arvif
->
vdev_id
,
0
,
info
->
bssid
);
arvif
->
aid
=
0
;
memcpy
(
arvif
->
bssid
,
info
->
bssid
,
ETH_ALEN
);
ret
=
ath10k_wmi_vdev_up
(
arvif
->
ar
,
arvif
->
vdev_id
,
arvif
->
aid
,
arvif
->
bssid
);
if
(
ret
)
{
if
(
ret
)
{
ath10k_warn
(
"Failed to bring up VDEV: %d
\n
"
,
ath10k_warn
(
"Failed to bring up VDEV: %d
\n
"
,
arvif
->
vdev_id
);
arvif
->
vdev_id
);
ath10k_vdev_stop
(
arvif
);
return
;
return
;
}
}
arvif
->
is_started
=
true
;
arvif
->
is_up
=
true
;
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac vdev %d up
\n
"
,
arvif
->
vdev_id
);
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac vdev %d up
\n
"
,
arvif
->
vdev_id
);
}
}
...
@@ -824,18 +889,18 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
...
@@ -824,18 +889,18 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
ath10k_warn
(
"Failed to delete IBSS self peer:%pM for VDEV:%d ret:%d
\n
"
,
ath10k_warn
(
"Failed to delete IBSS self peer:%pM for VDEV:%d ret:%d
\n
"
,
self_peer
,
arvif
->
vdev_id
,
ret
);
self_peer
,
arvif
->
vdev_id
,
ret
);
if
(
is_zero_ether_addr
(
arvif
->
u
.
ibss
.
bssid
))
if
(
is_zero_ether_addr
(
arvif
->
bssid
))
return
;
return
;
ret
=
ath10k_peer_delete
(
arvif
->
ar
,
arvif
->
vdev_id
,
ret
=
ath10k_peer_delete
(
arvif
->
ar
,
arvif
->
vdev_id
,
arvif
->
u
.
ibss
.
bssid
);
arvif
->
bssid
);
if
(
ret
)
{
if
(
ret
)
{
ath10k_warn
(
"Failed to delete IBSS BSSID peer:%pM for VDEV:%d ret:%d
\n
"
,
ath10k_warn
(
"Failed to delete IBSS BSSID peer:%pM for VDEV:%d ret:%d
\n
"
,
arvif
->
u
.
ibss
.
bssid
,
arvif
->
vdev_id
,
ret
);
arvif
->
bssid
,
arvif
->
vdev_id
,
ret
);
return
;
return
;
}
}
memset
(
arvif
->
u
.
ibss
.
bssid
,
0
,
ETH_ALEN
);
memset
(
arvif
->
bssid
,
0
,
ETH_ALEN
);
return
;
return
;
}
}
...
@@ -1017,7 +1082,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
...
@@ -1017,7 +1082,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
struct
wmi_peer_assoc_complete_arg
*
arg
)
struct
wmi_peer_assoc_complete_arg
*
arg
)
{
{
const
struct
ieee80211_sta_ht_cap
*
ht_cap
=
&
sta
->
ht_cap
;
const
struct
ieee80211_sta_ht_cap
*
ht_cap
=
&
sta
->
ht_cap
;
int
smps
;
int
i
,
n
;
int
i
,
n
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
lockdep_assert_held
(
&
ar
->
conf_mutex
);
...
@@ -1063,17 +1127,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
...
@@ -1063,17 +1127,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
arg
->
peer_flags
|=
WMI_PEER_STBC
;
arg
->
peer_flags
|=
WMI_PEER_STBC
;
}
}
smps
=
ht_cap
->
cap
&
IEEE80211_HT_CAP_SM_PS
;
smps
>>=
IEEE80211_HT_CAP_SM_PS_SHIFT
;
if
(
smps
==
WLAN_HT_CAP_SM_PS_STATIC
)
{
arg
->
peer_flags
|=
WMI_PEER_SPATIAL_MUX
;
arg
->
peer_flags
|=
WMI_PEER_STATIC_MIMOPS
;
}
else
if
(
smps
==
WLAN_HT_CAP_SM_PS_DYNAMIC
)
{
arg
->
peer_flags
|=
WMI_PEER_SPATIAL_MUX
;
arg
->
peer_flags
|=
WMI_PEER_DYN_MIMOPS
;
}
if
(
ht_cap
->
mcs
.
rx_mask
[
1
]
&&
ht_cap
->
mcs
.
rx_mask
[
2
])
if
(
ht_cap
->
mcs
.
rx_mask
[
1
]
&&
ht_cap
->
mcs
.
rx_mask
[
2
])
arg
->
peer_rate_caps
|=
WMI_RC_TS_FLAG
;
arg
->
peer_rate_caps
|=
WMI_RC_TS_FLAG
;
else
if
(
ht_cap
->
mcs
.
rx_mask
[
1
])
else
if
(
ht_cap
->
mcs
.
rx_mask
[
1
])
...
@@ -1083,8 +1136,23 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
...
@@ -1083,8 +1136,23 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
if
(
ht_cap
->
mcs
.
rx_mask
[
i
/
8
]
&
(
1
<<
i
%
8
))
if
(
ht_cap
->
mcs
.
rx_mask
[
i
/
8
]
&
(
1
<<
i
%
8
))
arg
->
peer_ht_rates
.
rates
[
n
++
]
=
i
;
arg
->
peer_ht_rates
.
rates
[
n
++
]
=
i
;
arg
->
peer_ht_rates
.
num_rates
=
n
;
/*
arg
->
peer_num_spatial_streams
=
max
((
n
+
7
)
/
8
,
1
);
* This is a workaround for HT-enabled STAs which break the spec
* and have no HT capabilities RX mask (no HT RX MCS map).
*
* As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
* MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
*
* Firmware asserts if such situation occurs.
*/
if
(
n
==
0
)
{
arg
->
peer_ht_rates
.
num_rates
=
8
;
for
(
i
=
0
;
i
<
arg
->
peer_ht_rates
.
num_rates
;
i
++
)
arg
->
peer_ht_rates
.
rates
[
i
]
=
i
;
}
else
{
arg
->
peer_ht_rates
.
num_rates
=
n
;
arg
->
peer_num_spatial_streams
=
sta
->
rx_nss
;
}
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac ht peer %pM mcs cnt %d nss %d
\n
"
,
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac ht peer %pM mcs cnt %d nss %d
\n
"
,
arg
->
addr
,
arg
->
addr
,
...
@@ -1092,27 +1160,20 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
...
@@ -1092,27 +1160,20 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
arg
->
peer_num_spatial_streams
);
arg
->
peer_num_spatial_streams
);
}
}
static
void
ath10k_peer_assoc_h_qos_ap
(
struct
ath10k
*
ar
,
static
int
ath10k_peer_assoc_qos_ap
(
struct
ath10k
*
ar
,
struct
ath10k_vif
*
arvif
,
struct
ath10k_vif
*
arvif
,
struct
ieee80211_sta
*
sta
,
struct
ieee80211_sta
*
sta
)
struct
ieee80211_bss_conf
*
bss_conf
,
struct
wmi_peer_assoc_complete_arg
*
arg
)
{
{
u32
uapsd
=
0
;
u32
uapsd
=
0
;
u32
max_sp
=
0
;
u32
max_sp
=
0
;
int
ret
=
0
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
lockdep_assert_held
(
&
ar
->
conf_mutex
);
if
(
sta
->
wme
)
arg
->
peer_flags
|=
WMI_PEER_QOS
;
if
(
sta
->
wme
&&
sta
->
uapsd_queues
)
{
if
(
sta
->
wme
&&
sta
->
uapsd_queues
)
{
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac uapsd_queues 0x%x max_sp %d
\n
"
,
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac uapsd_queues 0x%x max_sp %d
\n
"
,
sta
->
uapsd_queues
,
sta
->
max_sp
);
sta
->
uapsd_queues
,
sta
->
max_sp
);
arg
->
peer_flags
|=
WMI_PEER_APSD
;
arg
->
peer_rate_caps
|=
WMI_RC_UAPSD_FLAG
;
if
(
sta
->
uapsd_queues
&
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
)
if
(
sta
->
uapsd_queues
&
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
)
uapsd
|=
WMI_AP_PS_UAPSD_AC3_DELIVERY_EN
|
uapsd
|=
WMI_AP_PS_UAPSD_AC3_DELIVERY_EN
|
WMI_AP_PS_UAPSD_AC3_TRIGGER_EN
;
WMI_AP_PS_UAPSD_AC3_TRIGGER_EN
;
...
@@ -1130,35 +1191,40 @@ static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar,
...
@@ -1130,35 +1191,40 @@ static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar,
if
(
sta
->
max_sp
<
MAX_WMI_AP_PS_PEER_PARAM_MAX_SP
)
if
(
sta
->
max_sp
<
MAX_WMI_AP_PS_PEER_PARAM_MAX_SP
)
max_sp
=
sta
->
max_sp
;
max_sp
=
sta
->
max_sp
;
ath10k_wmi_set_ap_ps_param
(
ar
,
arvif
->
vdev_id
,
ret
=
ath10k_wmi_set_ap_ps_param
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
,
sta
->
addr
,
WMI_AP_PS_PEER_PARAM_UAPSD
,
WMI_AP_PS_PEER_PARAM_UAPSD
,
uapsd
);
uapsd
);
if
(
ret
)
{
ath10k_warn
(
"failed to set ap ps peer param uapsd: %d
\n
"
,
ret
);
return
ret
;
}
ath10k_wmi_set_ap_ps_param
(
ar
,
arvif
->
vdev_id
,
ret
=
ath10k_wmi_set_ap_ps_param
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
,
sta
->
addr
,
WMI_AP_PS_PEER_PARAM_MAX_SP
,
WMI_AP_PS_PEER_PARAM_MAX_SP
,
max_sp
);
max_sp
);
if
(
ret
)
{
ath10k_warn
(
"failed to set ap ps peer param max sp: %d
\n
"
,
ret
);
return
ret
;
}
/* TODO setup this based on STA listen interval and
/* TODO setup this based on STA listen interval and
beacon interval. Currently we don't know
beacon interval. Currently we don't know
sta->listen_interval - mac80211 patch required.
sta->listen_interval - mac80211 patch required.
Currently use 10 seconds */
Currently use 10 seconds */
ath10k_wmi_set_ap_ps_param
(
ar
,
arvif
->
vdev_id
,
ret
=
ath10k_wmi_set_ap_ps_param
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
,
sta
->
addr
,
WMI_AP_PS_PEER_PARAM_AGEOUT_TIME
,
10
);
WMI_AP_PS_PEER_PARAM_AGEOUT_TIME
,
if
(
ret
)
{
10
);
ath10k_warn
(
"failed to set ap ps peer param ageout time: %d
\n
"
,
ret
);
return
ret
;
}
}
}
}
static
void
ath10k_peer_assoc_h_qos_sta
(
struct
ath10k
*
ar
,
return
0
;
struct
ath10k_vif
*
arvif
,
struct
ieee80211_sta
*
sta
,
struct
ieee80211_bss_conf
*
bss_conf
,
struct
wmi_peer_assoc_complete_arg
*
arg
)
{
if
(
bss_conf
->
qos
)
arg
->
peer_flags
|=
WMI_PEER_QOS
;
}
}
static
void
ath10k_peer_assoc_h_vht
(
struct
ath10k
*
ar
,
static
void
ath10k_peer_assoc_h_vht
(
struct
ath10k
*
ar
,
...
@@ -1211,10 +1277,17 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
...
@@ -1211,10 +1277,17 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
{
{
switch
(
arvif
->
vdev_type
)
{
switch
(
arvif
->
vdev_type
)
{
case
WMI_VDEV_TYPE_AP
:
case
WMI_VDEV_TYPE_AP
:
ath10k_peer_assoc_h_qos_ap
(
ar
,
arvif
,
sta
,
bss_conf
,
arg
);
if
(
sta
->
wme
)
arg
->
peer_flags
|=
WMI_PEER_QOS
;
if
(
sta
->
wme
&&
sta
->
uapsd_queues
)
{
arg
->
peer_flags
|=
WMI_PEER_APSD
;
arg
->
peer_rate_caps
|=
WMI_RC_UAPSD_FLAG
;
}
break
;
break
;
case
WMI_VDEV_TYPE_STA
:
case
WMI_VDEV_TYPE_STA
:
ath10k_peer_assoc_h_qos_sta
(
ar
,
arvif
,
sta
,
bss_conf
,
arg
);
if
(
bss_conf
->
qos
)
arg
->
peer_flags
|=
WMI_PEER_QOS
;
break
;
break
;
default:
default:
break
;
break
;
...
@@ -1293,6 +1366,33 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar,
...
@@ -1293,6 +1366,33 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar,
return
0
;
return
0
;
}
}
static
const
u32
ath10k_smps_map
[]
=
{
[
WLAN_HT_CAP_SM_PS_STATIC
]
=
WMI_PEER_SMPS_STATIC
,
[
WLAN_HT_CAP_SM_PS_DYNAMIC
]
=
WMI_PEER_SMPS_DYNAMIC
,
[
WLAN_HT_CAP_SM_PS_INVALID
]
=
WMI_PEER_SMPS_PS_NONE
,
[
WLAN_HT_CAP_SM_PS_DISABLED
]
=
WMI_PEER_SMPS_PS_NONE
,
};
static
int
ath10k_setup_peer_smps
(
struct
ath10k
*
ar
,
struct
ath10k_vif
*
arvif
,
const
u8
*
addr
,
const
struct
ieee80211_sta_ht_cap
*
ht_cap
)
{
int
smps
;
if
(
!
ht_cap
->
ht_supported
)
return
0
;
smps
=
ht_cap
->
cap
&
IEEE80211_HT_CAP_SM_PS
;
smps
>>=
IEEE80211_HT_CAP_SM_PS_SHIFT
;
if
(
smps
>=
ARRAY_SIZE
(
ath10k_smps_map
))
return
-
EINVAL
;
return
ath10k_wmi_peer_set_param
(
ar
,
arvif
->
vdev_id
,
addr
,
WMI_PEER_SMPS_STATE
,
ath10k_smps_map
[
smps
]);
}
/* can be called only in mac80211 callbacks due to `key_count` usage */
/* can be called only in mac80211 callbacks due to `key_count` usage */
static
void
ath10k_bss_assoc
(
struct
ieee80211_hw
*
hw
,
static
void
ath10k_bss_assoc
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_vif
*
vif
,
...
@@ -1300,6 +1400,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
...
@@ -1300,6 +1400,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
{
{
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
struct
ieee80211_sta_ht_cap
ht_cap
;
struct
wmi_peer_assoc_complete_arg
peer_arg
;
struct
wmi_peer_assoc_complete_arg
peer_arg
;
struct
ieee80211_sta
*
ap_sta
;
struct
ieee80211_sta
*
ap_sta
;
int
ret
;
int
ret
;
...
@@ -1316,6 +1417,10 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
...
@@ -1316,6 +1417,10 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
return
;
return
;
}
}
/* ap_sta must be accessed only within rcu section which must be left
* before calling ath10k_setup_peer_smps() which might sleep. */
ht_cap
=
ap_sta
->
ht_cap
;
ret
=
ath10k_peer_assoc_prepare
(
ar
,
arvif
,
ap_sta
,
ret
=
ath10k_peer_assoc_prepare
(
ar
,
arvif
,
ap_sta
,
bss_conf
,
&
peer_arg
);
bss_conf
,
&
peer_arg
);
if
(
ret
)
{
if
(
ret
)
{
...
@@ -1334,15 +1439,27 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
...
@@ -1334,15 +1439,27 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
return
;
return
;
}
}
ret
=
ath10k_setup_peer_smps
(
ar
,
arvif
,
bss_conf
->
bssid
,
&
ht_cap
);
if
(
ret
)
{
ath10k_warn
(
"failed to setup peer SMPS: %d
\n
"
,
ret
);
return
;
}
ath10k_dbg
(
ATH10K_DBG_MAC
,
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac vdev %d up (associated) bssid %pM aid %d
\n
"
,
"mac vdev %d up (associated) bssid %pM aid %d
\n
"
,
arvif
->
vdev_id
,
bss_conf
->
bssid
,
bss_conf
->
aid
);
arvif
->
vdev_id
,
bss_conf
->
bssid
,
bss_conf
->
aid
);
ret
=
ath10k_wmi_vdev_up
(
ar
,
arvif
->
vdev_id
,
bss_conf
->
aid
,
arvif
->
aid
=
bss_conf
->
aid
;
bss_conf
->
bssid
);
memcpy
(
arvif
->
bssid
,
bss_conf
->
bssid
,
ETH_ALEN
);
if
(
ret
)
ret
=
ath10k_wmi_vdev_up
(
ar
,
arvif
->
vdev_id
,
arvif
->
aid
,
arvif
->
bssid
);
if
(
ret
)
{
ath10k_warn
(
"VDEV: %d up failed: ret %d
\n
"
,
ath10k_warn
(
"VDEV: %d up failed: ret %d
\n
"
,
arvif
->
vdev_id
,
ret
);
arvif
->
vdev_id
,
ret
);
return
;
}
arvif
->
is_up
=
true
;
}
}
/*
/*
...
@@ -1382,6 +1499,9 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
...
@@ -1382,6 +1499,9 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
ret
=
ath10k_wmi_vdev_down
(
ar
,
arvif
->
vdev_id
);
ret
=
ath10k_wmi_vdev_down
(
ar
,
arvif
->
vdev_id
);
arvif
->
def_wep_key_idx
=
0
;
arvif
->
def_wep_key_idx
=
0
;
arvif
->
is_started
=
false
;
arvif
->
is_up
=
false
;
}
}
static
int
ath10k_station_assoc
(
struct
ath10k
*
ar
,
struct
ath10k_vif
*
arvif
,
static
int
ath10k_station_assoc
(
struct
ath10k
*
ar
,
struct
ath10k_vif
*
arvif
,
...
@@ -1406,12 +1526,25 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
...
@@ -1406,12 +1526,25 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
return
ret
;
return
ret
;
}
}
ret
=
ath10k_setup_peer_smps
(
ar
,
arvif
,
sta
->
addr
,
&
sta
->
ht_cap
);
if
(
ret
)
{
ath10k_warn
(
"failed to setup peer SMPS: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
ath10k_install_peer_wep_keys
(
arvif
,
sta
->
addr
);
ret
=
ath10k_install_peer_wep_keys
(
arvif
,
sta
->
addr
);
if
(
ret
)
{
if
(
ret
)
{
ath10k_warn
(
"could not install peer wep keys (%d)
\n
"
,
ret
);
ath10k_warn
(
"could not install peer wep keys (%d)
\n
"
,
ret
);
return
ret
;
return
ret
;
}
}
ret
=
ath10k_peer_assoc_qos_ap
(
ar
,
arvif
,
sta
);
if
(
ret
)
{
ath10k_warn
(
"could not set qos params for STA %pM, %d
\n
"
,
sta
->
addr
,
ret
);
return
ret
;
}
return
ret
;
return
ret
;
}
}
...
@@ -1547,9 +1680,9 @@ static void ath10k_regd_update(struct ath10k *ar)
...
@@ -1547,9 +1680,9 @@ static void ath10k_regd_update(struct ath10k *ar)
/* Target allows setting up per-band regdomain but ath_common provides
/* Target allows setting up per-band regdomain but ath_common provides
* a combined one only */
* a combined one only */
ret
=
ath10k_wmi_pdev_set_regdomain
(
ar
,
ret
=
ath10k_wmi_pdev_set_regdomain
(
ar
,
regpair
->
reg
DmnEnum
,
regpair
->
reg
_domain
,
regpair
->
reg
DmnEnum
,
/* 2ghz */
regpair
->
reg
_domain
,
/* 2ghz */
regpair
->
reg
DmnEnum
,
/* 5ghz */
regpair
->
reg
_domain
,
/* 5ghz */
regpair
->
reg_2ghz_ctl
,
regpair
->
reg_2ghz_ctl
,
regpair
->
reg_5ghz_ctl
);
regpair
->
reg_5ghz_ctl
);
if
(
ret
)
if
(
ret
)
...
@@ -2100,11 +2233,29 @@ static int ath10k_start(struct ieee80211_hw *hw)
...
@@ -2100,11 +2233,29 @@ static int ath10k_start(struct ieee80211_hw *hw)
ath10k_warn
(
"could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)
\n
"
,
ath10k_warn
(
"could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)
\n
"
,
ret
);
ret
);
/*
* By default FW set ARP frames ac to voice (6). In that case ARP
* exchange is not working properly for UAPSD enabled AP. ARP requests
* which arrives with access category 0 are processed by network stack
* and send back with access category 0, but FW changes access category
* to 6. Set ARP frames access category to best effort (0) solves
* this problem.
*/
ret
=
ath10k_wmi_pdev_set_param
(
ar
,
ar
->
wmi
.
pdev_param
->
arp_ac_override
,
0
);
if
(
ret
)
{
ath10k_warn
(
"could not set arp ac override parameter: %d
\n
"
,
ret
);
goto
exit
;
}
ath10k_regd_update
(
ar
);
ath10k_regd_update
(
ar
);
ret
=
0
;
exit:
exit:
mutex_unlock
(
&
ar
->
conf_mutex
);
mutex_unlock
(
&
ar
->
conf_mutex
);
return
0
;
return
ret
;
}
}
static
void
ath10k_stop
(
struct
ieee80211_hw
*
hw
)
static
void
ath10k_stop
(
struct
ieee80211_hw
*
hw
)
...
@@ -2145,6 +2296,98 @@ static int ath10k_config_ps(struct ath10k *ar)
...
@@ -2145,6 +2296,98 @@ static int ath10k_config_ps(struct ath10k *ar)
return
ret
;
return
ret
;
}
}
static
const
char
*
chandef_get_width
(
enum
nl80211_chan_width
width
)
{
switch
(
width
)
{
case
NL80211_CHAN_WIDTH_20_NOHT
:
return
"20 (noht)"
;
case
NL80211_CHAN_WIDTH_20
:
return
"20"
;
case
NL80211_CHAN_WIDTH_40
:
return
"40"
;
case
NL80211_CHAN_WIDTH_80
:
return
"80"
;
case
NL80211_CHAN_WIDTH_80P80
:
return
"80+80"
;
case
NL80211_CHAN_WIDTH_160
:
return
"160"
;
case
NL80211_CHAN_WIDTH_5
:
return
"5"
;
case
NL80211_CHAN_WIDTH_10
:
return
"10"
;
}
return
"?"
;
}
static
void
ath10k_config_chan
(
struct
ath10k
*
ar
)
{
struct
ath10k_vif
*
arvif
;
bool
monitor_was_enabled
;
int
ret
;
lockdep_assert_held
(
&
ar
->
conf_mutex
);
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac config channel to %dMHz (cf1 %dMHz cf2 %dMHz width %s)
\n
"
,
ar
->
chandef
.
chan
->
center_freq
,
ar
->
chandef
.
center_freq1
,
ar
->
chandef
.
center_freq2
,
chandef_get_width
(
ar
->
chandef
.
width
));
/* First stop monitor interface. Some FW versions crash if there's a
* lone monitor interface. */
monitor_was_enabled
=
ar
->
monitor_enabled
;
if
(
ar
->
monitor_enabled
)
ath10k_monitor_stop
(
ar
);
list_for_each_entry
(
arvif
,
&
ar
->
arvifs
,
list
)
{
if
(
!
arvif
->
is_started
)
continue
;
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_MONITOR
)
continue
;
ret
=
ath10k_vdev_stop
(
arvif
);
if
(
ret
)
{
ath10k_warn
(
"could not stop vdev %d (%d)
\n
"
,
arvif
->
vdev_id
,
ret
);
continue
;
}
}
/* all vdevs are now stopped - now attempt to restart them */
list_for_each_entry
(
arvif
,
&
ar
->
arvifs
,
list
)
{
if
(
!
arvif
->
is_started
)
continue
;
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_MONITOR
)
continue
;
ret
=
ath10k_vdev_start
(
arvif
);
if
(
ret
)
{
ath10k_warn
(
"could not start vdev %d (%d)
\n
"
,
arvif
->
vdev_id
,
ret
);
continue
;
}
if
(
!
arvif
->
is_up
)
continue
;
ret
=
ath10k_wmi_vdev_up
(
arvif
->
ar
,
arvif
->
vdev_id
,
arvif
->
aid
,
arvif
->
bssid
);
if
(
ret
)
{
ath10k_warn
(
"could not bring vdev up %d (%d)
\n
"
,
arvif
->
vdev_id
,
ret
);
continue
;
}
}
if
(
monitor_was_enabled
)
ath10k_monitor_start
(
ar
,
ar
->
monitor_vdev_id
);
}
static
int
ath10k_config
(
struct
ieee80211_hw
*
hw
,
u32
changed
)
static
int
ath10k_config
(
struct
ieee80211_hw
*
hw
,
u32
changed
)
{
{
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k
*
ar
=
hw
->
priv
;
...
@@ -2165,6 +2408,11 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
...
@@ -2165,6 +2408,11 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
spin_unlock_bh
(
&
ar
->
data_lock
);
spin_unlock_bh
(
&
ar
->
data_lock
);
ath10k_config_radar_detection
(
ar
);
ath10k_config_radar_detection
(
ar
);
if
(
!
cfg80211_chandef_identical
(
&
ar
->
chandef
,
&
conf
->
chandef
))
{
ar
->
chandef
=
conf
->
chandef
;
ath10k_config_chan
(
ar
);
}
}
}
if
(
changed
&
IEEE80211_CONF_CHANGE_POWER
)
{
if
(
changed
&
IEEE80211_CONF_CHANGE_POWER
)
{
...
@@ -2214,7 +2462,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
...
@@ -2214,7 +2462,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
enum
wmi_sta_powersave_param
param
;
enum
wmi_sta_powersave_param
param
;
int
ret
=
0
;
int
ret
=
0
;
u32
value
,
param_id
;
u32
value
;
int
bit
;
int
bit
;
u32
vdev_param
;
u32
vdev_param
;
...
@@ -2307,12 +2555,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
...
@@ -2307,12 +2555,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
goto
err_vdev_delete
;
goto
err_vdev_delete
;
}
}
param_id
=
ar
->
wmi
.
pdev_param
->
sta_kickout_th
;
ret
=
ath10k_mac_set_kickout
(
arvif
)
;
if
(
ret
)
{
/* Disable STA KICKOUT functionality in FW */
ath10k_warn
(
"Failed to set kickout parameters: %d
\n
"
,
ret
=
ath10k_wmi_pdev_set_param
(
ar
,
param_id
,
0
);
ret
);
if
(
ret
)
goto
err_peer_delete
;
ath10k_warn
(
"Failed to disable STA KICKOUT
\n
"
);
}
}
}
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_STA
)
{
if
(
arvif
->
vdev_type
==
WMI_VDEV_TYPE_STA
)
{
...
@@ -2559,15 +2807,20 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
...
@@ -2559,15 +2807,20 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
* this is never erased as we it for crypto key
* this is never erased as we it for crypto key
* clearing; this is FW requirement
* clearing; this is FW requirement
*/
*/
memcpy
(
arvif
->
u
.
sta
.
bssid
,
info
->
bssid
,
memcpy
(
arvif
->
bssid
,
info
->
bssid
,
ETH_ALEN
);
ETH_ALEN
);
ath10k_dbg
(
ATH10K_DBG_MAC
,
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac vdev %d start %pM
\n
"
,
"mac vdev %d start %pM
\n
"
,
arvif
->
vdev_id
,
info
->
bssid
);
arvif
->
vdev_id
,
info
->
bssid
);
/* FIXME: check return value */
ret
=
ath10k_vdev_start
(
arvif
);
ret
=
ath10k_vdev_start
(
arvif
);
if
(
ret
)
{
ath10k_warn
(
"failed to start vdev: %d
\n
"
,
ret
);
goto
exit
;
}
arvif
->
is_started
=
true
;
}
}
/*
/*
...
@@ -2576,7 +2829,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
...
@@ -2576,7 +2829,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
* IBSS in order to remove BSSID peer.
* IBSS in order to remove BSSID peer.
*/
*/
if
(
vif
->
type
==
NL80211_IFTYPE_ADHOC
)
if
(
vif
->
type
==
NL80211_IFTYPE_ADHOC
)
memcpy
(
arvif
->
u
.
ibss
.
bssid
,
info
->
bssid
,
memcpy
(
arvif
->
bssid
,
info
->
bssid
,
ETH_ALEN
);
ETH_ALEN
);
}
}
}
}
...
@@ -2645,6 +2898,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
...
@@ -2645,6 +2898,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
ath10k_bss_assoc
(
hw
,
vif
,
info
);
ath10k_bss_assoc
(
hw
,
vif
,
info
);
}
}
exit:
mutex_unlock
(
&
ar
->
conf_mutex
);
mutex_unlock
(
&
ar
->
conf_mutex
);
}
}
...
@@ -2850,6 +3104,69 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
...
@@ -2850,6 +3104,69 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return
ret
;
return
ret
;
}
}
static
void
ath10k_sta_rc_update_wk
(
struct
work_struct
*
wk
)
{
struct
ath10k
*
ar
;
struct
ath10k_vif
*
arvif
;
struct
ath10k_sta
*
arsta
;
struct
ieee80211_sta
*
sta
;
u32
changed
,
bw
,
nss
,
smps
;
int
err
;
arsta
=
container_of
(
wk
,
struct
ath10k_sta
,
update_wk
);
sta
=
container_of
((
void
*
)
arsta
,
struct
ieee80211_sta
,
drv_priv
);
arvif
=
arsta
->
arvif
;
ar
=
arvif
->
ar
;
spin_lock_bh
(
&
ar
->
data_lock
);
changed
=
arsta
->
changed
;
arsta
->
changed
=
0
;
bw
=
arsta
->
bw
;
nss
=
arsta
->
nss
;
smps
=
arsta
->
smps
;
spin_unlock_bh
(
&
ar
->
data_lock
);
mutex_lock
(
&
ar
->
conf_mutex
);
if
(
changed
&
IEEE80211_RC_BW_CHANGED
)
{
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac update sta %pM peer bw %d
\n
"
,
sta
->
addr
,
bw
);
err
=
ath10k_wmi_peer_set_param
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
,
WMI_PEER_CHAN_WIDTH
,
bw
);
if
(
err
)
ath10k_warn
(
"failed to update STA %pM peer bw %d: %d
\n
"
,
sta
->
addr
,
bw
,
err
);
}
if
(
changed
&
IEEE80211_RC_NSS_CHANGED
)
{
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac update sta %pM nss %d
\n
"
,
sta
->
addr
,
nss
);
err
=
ath10k_wmi_peer_set_param
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
,
WMI_PEER_NSS
,
nss
);
if
(
err
)
ath10k_warn
(
"failed to update STA %pM nss %d: %d
\n
"
,
sta
->
addr
,
nss
,
err
);
}
if
(
changed
&
IEEE80211_RC_SMPS_CHANGED
)
{
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac update sta %pM smps %d
\n
"
,
sta
->
addr
,
smps
);
err
=
ath10k_wmi_peer_set_param
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
,
WMI_PEER_SMPS_STATE
,
smps
);
if
(
err
)
ath10k_warn
(
"failed to update STA %pM smps %d: %d
\n
"
,
sta
->
addr
,
smps
,
err
);
}
mutex_unlock
(
&
ar
->
conf_mutex
);
}
static
int
ath10k_sta_state
(
struct
ieee80211_hw
*
hw
,
static
int
ath10k_sta_state
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
struct
ieee80211_sta
*
sta
,
...
@@ -2858,9 +3175,15 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
...
@@ -2858,9 +3175,15 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
{
{
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
struct
ath10k_vif
*
arvif
=
ath10k_vif_to_arvif
(
vif
);
struct
ath10k_sta
*
arsta
=
(
struct
ath10k_sta
*
)
sta
->
drv_priv
;
int
max_num_peers
;
int
max_num_peers
;
int
ret
=
0
;
int
ret
=
0
;
/* cancel must be done outside the mutex to avoid deadlock */
if
((
old_state
==
IEEE80211_STA_NONE
&&
new_state
==
IEEE80211_STA_NOTEXIST
))
cancel_work_sync
(
&
arsta
->
update_wk
);
mutex_lock
(
&
ar
->
conf_mutex
);
mutex_lock
(
&
ar
->
conf_mutex
);
if
(
old_state
==
IEEE80211_STA_NOTEXIST
&&
if
(
old_state
==
IEEE80211_STA_NOTEXIST
&&
...
@@ -2885,6 +3208,10 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
...
@@ -2885,6 +3208,10 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
"mac vdev %d peer create %pM (new sta) num_peers %d
\n
"
,
"mac vdev %d peer create %pM (new sta) num_peers %d
\n
"
,
arvif
->
vdev_id
,
sta
->
addr
,
ar
->
num_peers
);
arvif
->
vdev_id
,
sta
->
addr
,
ar
->
num_peers
);
memset
(
arsta
,
0
,
sizeof
(
*
arsta
));
arsta
->
arvif
=
arvif
;
INIT_WORK
(
&
arsta
->
update_wk
,
ath10k_sta_rc_update_wk
);
ret
=
ath10k_peer_create
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
);
ret
=
ath10k_peer_create
(
ar
,
arvif
->
vdev_id
,
sta
->
addr
);
if
(
ret
)
if
(
ret
)
ath10k_warn
(
"Failed to add peer %pM for vdev %d when adding a new sta: %i
\n
"
,
ath10k_warn
(
"Failed to add peer %pM for vdev %d when adding a new sta: %i
\n
"
,
...
@@ -3234,23 +3561,14 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
...
@@ -3234,23 +3561,14 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k
*
ar
=
hw
->
priv
;
int
ret
;
int
ret
;
ar
->
is_target_paused
=
false
;
mutex_lock
(
&
ar
->
conf_mutex
)
;
ret
=
ath10k_w
mi_pdev_suspend_target
(
ar
);
ret
=
ath10k_w
ait_for_suspend
(
ar
,
WMI_PDEV_SUSPEND
);
if
(
ret
)
{
if
(
ret
)
{
ath10k_warn
(
"could not suspend target (%d)
\n
"
,
ret
);
if
(
ret
==
-
ETIMEDOUT
)
return
1
;
goto
resume
;
}
ret
=
1
;
goto
exit
;
ret
=
wait_event_interruptible_timeout
(
ar
->
event_queue
,
ar
->
is_target_paused
==
true
,
1
*
HZ
);
if
(
ret
<
0
)
{
ath10k_warn
(
"suspend interrupted (%d)
\n
"
,
ret
);
goto
resume
;
}
else
if
(
ret
==
0
)
{
ath10k_warn
(
"suspend timed out - target pause event never came
\n
"
);
goto
resume
;
}
}
ret
=
ath10k_hif_suspend
(
ar
);
ret
=
ath10k_hif_suspend
(
ar
);
...
@@ -3259,12 +3577,17 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
...
@@ -3259,12 +3577,17 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
goto
resume
;
goto
resume
;
}
}
return
0
;
ret
=
0
;
goto
exit
;
resume:
resume:
ret
=
ath10k_wmi_pdev_resume_target
(
ar
);
ret
=
ath10k_wmi_pdev_resume_target
(
ar
);
if
(
ret
)
if
(
ret
)
ath10k_warn
(
"could not resume target (%d)
\n
"
,
ret
);
ath10k_warn
(
"could not resume target (%d)
\n
"
,
ret
);
return
1
;
ret
=
1
;
exit:
mutex_unlock
(
&
ar
->
conf_mutex
);
return
ret
;
}
}
static
int
ath10k_resume
(
struct
ieee80211_hw
*
hw
)
static
int
ath10k_resume
(
struct
ieee80211_hw
*
hw
)
...
@@ -3272,19 +3595,26 @@ static int ath10k_resume(struct ieee80211_hw *hw)
...
@@ -3272,19 +3595,26 @@ static int ath10k_resume(struct ieee80211_hw *hw)
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k
*
ar
=
hw
->
priv
;
int
ret
;
int
ret
;
mutex_lock
(
&
ar
->
conf_mutex
);
ret
=
ath10k_hif_resume
(
ar
);
ret
=
ath10k_hif_resume
(
ar
);
if
(
ret
)
{
if
(
ret
)
{
ath10k_warn
(
"could not resume hif (%d)
\n
"
,
ret
);
ath10k_warn
(
"could not resume hif (%d)
\n
"
,
ret
);
return
1
;
ret
=
1
;
goto
exit
;
}
}
ret
=
ath10k_wmi_pdev_resume_target
(
ar
);
ret
=
ath10k_wmi_pdev_resume_target
(
ar
);
if
(
ret
)
{
if
(
ret
)
{
ath10k_warn
(
"could not resume target (%d)
\n
"
,
ret
);
ath10k_warn
(
"could not resume target (%d)
\n
"
,
ret
);
return
1
;
ret
=
1
;
goto
exit
;
}
}
return
0
;
ret
=
0
;
exit:
mutex_unlock
(
&
ar
->
conf_mutex
);
return
ret
;
}
}
#endif
#endif
...
@@ -3640,6 +3970,96 @@ static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
...
@@ -3640,6 +3970,96 @@ static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
return
ath10k_set_fixed_rate_param
(
arvif
,
fixed_rate
,
fixed_nss
);
return
ath10k_set_fixed_rate_param
(
arvif
,
fixed_rate
,
fixed_nss
);
}
}
static
void
ath10k_channel_switch_beacon
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_chan_def
*
chandef
)
{
/* there's no need to do anything here. vif->csa_active is enough */
return
;
}
static
void
ath10k_sta_rc_update
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
u32
changed
)
{
struct
ath10k
*
ar
=
hw
->
priv
;
struct
ath10k_sta
*
arsta
=
(
struct
ath10k_sta
*
)
sta
->
drv_priv
;
u32
bw
,
smps
;
spin_lock_bh
(
&
ar
->
data_lock
);
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac sta rc update for %pM changed %08x bw %d nss %d smps %d
\n
"
,
sta
->
addr
,
changed
,
sta
->
bandwidth
,
sta
->
rx_nss
,
sta
->
smps_mode
);
if
(
changed
&
IEEE80211_RC_BW_CHANGED
)
{
bw
=
WMI_PEER_CHWIDTH_20MHZ
;
switch
(
sta
->
bandwidth
)
{
case
IEEE80211_STA_RX_BW_20
:
bw
=
WMI_PEER_CHWIDTH_20MHZ
;
break
;
case
IEEE80211_STA_RX_BW_40
:
bw
=
WMI_PEER_CHWIDTH_40MHZ
;
break
;
case
IEEE80211_STA_RX_BW_80
:
bw
=
WMI_PEER_CHWIDTH_80MHZ
;
break
;
case
IEEE80211_STA_RX_BW_160
:
ath10k_warn
(
"mac sta rc update for %pM: invalid bw %d
\n
"
,
sta
->
addr
,
sta
->
bandwidth
);
bw
=
WMI_PEER_CHWIDTH_20MHZ
;
break
;
}
arsta
->
bw
=
bw
;
}
if
(
changed
&
IEEE80211_RC_NSS_CHANGED
)
arsta
->
nss
=
sta
->
rx_nss
;
if
(
changed
&
IEEE80211_RC_SMPS_CHANGED
)
{
smps
=
WMI_PEER_SMPS_PS_NONE
;
switch
(
sta
->
smps_mode
)
{
case
IEEE80211_SMPS_AUTOMATIC
:
case
IEEE80211_SMPS_OFF
:
smps
=
WMI_PEER_SMPS_PS_NONE
;
break
;
case
IEEE80211_SMPS_STATIC
:
smps
=
WMI_PEER_SMPS_STATIC
;
break
;
case
IEEE80211_SMPS_DYNAMIC
:
smps
=
WMI_PEER_SMPS_DYNAMIC
;
break
;
case
IEEE80211_SMPS_NUM_MODES
:
ath10k_warn
(
"mac sta rc update for %pM: invalid smps: %d
\n
"
,
sta
->
addr
,
sta
->
smps_mode
);
smps
=
WMI_PEER_SMPS_PS_NONE
;
break
;
}
arsta
->
smps
=
smps
;
}
if
(
changed
&
IEEE80211_RC_SUPP_RATES_CHANGED
)
{
/* FIXME: Not implemented. Probably the only way to do it would
* be to re-assoc the peer. */
changed
&=
~
IEEE80211_RC_SUPP_RATES_CHANGED
;
ath10k_dbg
(
ATH10K_DBG_MAC
,
"mac sta rc update for %pM: changing supported rates not implemented
\n
"
,
sta
->
addr
);
}
arsta
->
changed
|=
changed
;
spin_unlock_bh
(
&
ar
->
data_lock
);
ieee80211_queue_work
(
hw
,
&
arsta
->
update_wk
);
}
static
const
struct
ieee80211_ops
ath10k_ops
=
{
static
const
struct
ieee80211_ops
ath10k_ops
=
{
.
tx
=
ath10k_tx
,
.
tx
=
ath10k_tx
,
.
start
=
ath10k_start
,
.
start
=
ath10k_start
,
...
@@ -3663,6 +4083,8 @@ static const struct ieee80211_ops ath10k_ops = {
...
@@ -3663,6 +4083,8 @@ static const struct ieee80211_ops ath10k_ops = {
.
restart_complete
=
ath10k_restart_complete
,
.
restart_complete
=
ath10k_restart_complete
,
.
get_survey
=
ath10k_get_survey
,
.
get_survey
=
ath10k_get_survey
,
.
set_bitrate_mask
=
ath10k_set_bitrate_mask
,
.
set_bitrate_mask
=
ath10k_set_bitrate_mask
,
.
channel_switch_beacon
=
ath10k_channel_switch_beacon
,
.
sta_rc_update
=
ath10k_sta_rc_update
,
#ifdef CONFIG_PM
#ifdef CONFIG_PM
.
suspend
=
ath10k_suspend
,
.
suspend
=
ath10k_suspend
,
.
resume
=
ath10k_resume
,
.
resume
=
ath10k_resume
,
...
@@ -4038,10 +4460,12 @@ int ath10k_mac_register(struct ath10k *ar)
...
@@ -4038,10 +4460,12 @@ int ath10k_mac_register(struct ath10k *ar)
ar
->
hw
->
wiphy
->
max_scan_ie_len
=
WLAN_SCAN_PARAMS_MAX_IE_LEN
;
ar
->
hw
->
wiphy
->
max_scan_ie_len
=
WLAN_SCAN_PARAMS_MAX_IE_LEN
;
ar
->
hw
->
vif_data_size
=
sizeof
(
struct
ath10k_vif
);
ar
->
hw
->
vif_data_size
=
sizeof
(
struct
ath10k_vif
);
ar
->
hw
->
sta_data_size
=
sizeof
(
struct
ath10k_sta
);
ar
->
hw
->
max_listen_interval
=
ATH10K_MAX_HW_LISTEN_INTERVAL
;
ar
->
hw
->
max_listen_interval
=
ATH10K_MAX_HW_LISTEN_INTERVAL
;
ar
->
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
ar
->
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
ar
->
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_HAS_CHANNEL_SWITCH
;
ar
->
hw
->
wiphy
->
max_remain_on_channel_duration
=
5000
;
ar
->
hw
->
wiphy
->
max_remain_on_channel_duration
=
5000
;
ar
->
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_AP_UAPSD
;
ar
->
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_AP_UAPSD
;
...
...
drivers/net/wireless/ath/ath10k/pci.c
View file @
9e4b4269
...
@@ -64,7 +64,8 @@ static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
...
@@ -64,7 +64,8 @@ static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
int
num
);
int
num
);
static
void
ath10k_pci_rx_pipe_cleanup
(
struct
ath10k_pci_pipe
*
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_stop_ce
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_device_reset
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_cold_reset
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_warm_reset
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_wait_for_target_init
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_wait_for_target_init
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_init_irq
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_init_irq
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_deinit_irq
(
struct
ath10k
*
ar
);
static
int
ath10k_pci_deinit_irq
(
struct
ath10k
*
ar
);
...
@@ -833,9 +834,7 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
...
@@ -833,9 +834,7 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
ath10k_err
(
"firmware crashed!
\n
"
);
ath10k_err
(
"firmware crashed!
\n
"
);
ath10k_err
(
"hardware name %s version 0x%x
\n
"
,
ath10k_err
(
"hardware name %s version 0x%x
\n
"
,
ar
->
hw_params
.
name
,
ar
->
target_version
);
ar
->
hw_params
.
name
,
ar
->
target_version
);
ath10k_err
(
"firmware version: %u.%u.%u.%u
\n
"
,
ar
->
fw_version_major
,
ath10k_err
(
"firmware version: %s
\n
"
,
ar
->
hw
->
wiphy
->
fw_version
);
ar
->
fw_version_minor
,
ar
->
fw_version_release
,
ar
->
fw_version_build
);
host_addr
=
host_interest_item_address
(
HI_ITEM
(
hi_failure_state
));
host_addr
=
host_interest_item_address
(
HI_ITEM
(
hi_failure_state
));
ret
=
ath10k_pci_diag_read_mem
(
ar
,
host_addr
,
ret
=
ath10k_pci_diag_read_mem
(
ar
,
host_addr
,
...
@@ -1502,7 +1501,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
...
@@ -1502,7 +1501,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
* configuration during init. If ringbuffers are freed and the device
* configuration during init. If ringbuffers are freed and the device
* were to access them this could lead to memory corruption on the
* were to access them this could lead to memory corruption on the
* host. */
* host. */
ath10k_pci_
device
_reset
(
ar
);
ath10k_pci_
warm
_reset
(
ar
);
ar_pci
->
started
=
0
;
ar_pci
->
started
=
0
;
}
}
...
@@ -1993,7 +1992,94 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
...
@@ -1993,7 +1992,94 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
ath10k_pci_sleep
(
ar
);
ath10k_pci_sleep
(
ar
);
}
}
static
int
ath10k_pci_hif_power_up
(
struct
ath10k
*
ar
)
static
int
ath10k_pci_warm_reset
(
struct
ath10k
*
ar
)
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
int
ret
=
0
;
u32
val
;
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot performing warm chip reset
\n
"
);
ret
=
ath10k_do_pci_wake
(
ar
);
if
(
ret
)
{
ath10k_err
(
"failed to wake up target: %d
\n
"
,
ret
);
return
ret
;
}
/* debug */
val
=
ath10k_pci_read32
(
ar
,
SOC_CORE_BASE_ADDRESS
+
PCIE_INTR_CAUSE_ADDRESS
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot host cpu intr cause: 0x%08x
\n
"
,
val
);
val
=
ath10k_pci_read32
(
ar
,
SOC_CORE_BASE_ADDRESS
+
CPU_INTR_ADDRESS
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot target cpu intr cause: 0x%08x
\n
"
,
val
);
/* disable pending irqs */
ath10k_pci_write32
(
ar
,
SOC_CORE_BASE_ADDRESS
+
PCIE_INTR_ENABLE_ADDRESS
,
0
);
ath10k_pci_write32
(
ar
,
SOC_CORE_BASE_ADDRESS
+
PCIE_INTR_CLR_ADDRESS
,
~
0
);
msleep
(
100
);
/* clear fw indicator */
ath10k_pci_write32
(
ar
,
ar_pci
->
fw_indicator_address
,
0
);
/* clear target LF timer interrupts */
val
=
ath10k_pci_read32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_LF_TIMER_CONTROL0_ADDRESS
);
ath10k_pci_write32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_LF_TIMER_CONTROL0_ADDRESS
,
val
&
~
SOC_LF_TIMER_CONTROL0_ENABLE_MASK
);
/* reset CE */
val
=
ath10k_pci_read32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
);
ath10k_pci_write32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
,
val
|
SOC_RESET_CONTROL_CE_RST_MASK
);
val
=
ath10k_pci_read32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
);
msleep
(
10
);
/* unreset CE */
ath10k_pci_write32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
,
val
&
~
SOC_RESET_CONTROL_CE_RST_MASK
);
val
=
ath10k_pci_read32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
);
msleep
(
10
);
/* debug */
val
=
ath10k_pci_read32
(
ar
,
SOC_CORE_BASE_ADDRESS
+
PCIE_INTR_CAUSE_ADDRESS
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot host cpu intr cause: 0x%08x
\n
"
,
val
);
val
=
ath10k_pci_read32
(
ar
,
SOC_CORE_BASE_ADDRESS
+
CPU_INTR_ADDRESS
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot target cpu intr cause: 0x%08x
\n
"
,
val
);
/* CPU warm reset */
val
=
ath10k_pci_read32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
);
ath10k_pci_write32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
,
val
|
SOC_RESET_CONTROL_CPU_WARM_RST_MASK
);
val
=
ath10k_pci_read32
(
ar
,
RTC_SOC_BASE_ADDRESS
+
SOC_RESET_CONTROL_ADDRESS
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot target reset state: 0x%08x
\n
"
,
val
);
msleep
(
100
);
ath10k_dbg
(
ATH10K_DBG_BOOT
,
"boot warm reset complete
\n
"
);
ath10k_do_pci_sleep
(
ar
);
return
ret
;
}
static
int
__ath10k_pci_hif_power_up
(
struct
ath10k
*
ar
,
bool
cold_reset
)
{
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
const
char
*
irq_mode
;
const
char
*
irq_mode
;
...
@@ -2009,7 +2095,11 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
...
@@ -2009,7 +2095,11 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
* is in an unexpected state. We try to catch that here in order to
* is in an unexpected state. We try to catch that here in order to
* reset the Target and retry the probe.
* reset the Target and retry the probe.
*/
*/
ret
=
ath10k_pci_device_reset
(
ar
);
if
(
cold_reset
)
ret
=
ath10k_pci_cold_reset
(
ar
);
else
ret
=
ath10k_pci_warm_reset
(
ar
);
if
(
ret
)
{
if
(
ret
)
{
ath10k_err
(
"failed to reset target: %d
\n
"
,
ret
);
ath10k_err
(
"failed to reset target: %d
\n
"
,
ret
);
goto
err
;
goto
err
;
...
@@ -2079,7 +2169,7 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
...
@@ -2079,7 +2169,7 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
ath10k_pci_deinit_irq
(
ar
);
ath10k_pci_deinit_irq
(
ar
);
err_ce:
err_ce:
ath10k_pci_ce_deinit
(
ar
);
ath10k_pci_ce_deinit
(
ar
);
ath10k_pci_
device
_reset
(
ar
);
ath10k_pci_
warm
_reset
(
ar
);
err_ps:
err_ps:
if
(
!
test_bit
(
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
,
ar_pci
->
features
))
if
(
!
test_bit
(
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
,
ar_pci
->
features
))
ath10k_do_pci_sleep
(
ar
);
ath10k_do_pci_sleep
(
ar
);
...
@@ -2087,6 +2177,34 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
...
@@ -2087,6 +2177,34 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
return
ret
;
return
ret
;
}
}
static
int
ath10k_pci_hif_power_up
(
struct
ath10k
*
ar
)
{
int
ret
;
/*
* Hardware CUS232 version 2 has some issues with cold reset and the
* preferred (and safer) way to perform a device reset is through a
* warm reset.
*
* Warm reset doesn't always work though (notably after a firmware
* crash) so fall back to cold reset if necessary.
*/
ret
=
__ath10k_pci_hif_power_up
(
ar
,
false
);
if
(
ret
)
{
ath10k_warn
(
"failed to power up target using warm reset (%d), trying cold reset
\n
"
,
ret
);
ret
=
__ath10k_pci_hif_power_up
(
ar
,
true
);
if
(
ret
)
{
ath10k_err
(
"failed to power up target using cold reset too (%d)
\n
"
,
ret
);
return
ret
;
}
}
return
0
;
}
static
void
ath10k_pci_hif_power_down
(
struct
ath10k
*
ar
)
static
void
ath10k_pci_hif_power_down
(
struct
ath10k
*
ar
)
{
{
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
struct
ath10k_pci
*
ar_pci
=
ath10k_pci_priv
(
ar
);
...
@@ -2094,7 +2212,7 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar)
...
@@ -2094,7 +2212,7 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar)
ath10k_pci_free_early_irq
(
ar
);
ath10k_pci_free_early_irq
(
ar
);
ath10k_pci_kill_tasklet
(
ar
);
ath10k_pci_kill_tasklet
(
ar
);
ath10k_pci_deinit_irq
(
ar
);
ath10k_pci_deinit_irq
(
ar
);
ath10k_pci_
device
_reset
(
ar
);
ath10k_pci_
warm
_reset
(
ar
);
ath10k_pci_ce_deinit
(
ar
);
ath10k_pci_ce_deinit
(
ar
);
if
(
!
test_bit
(
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
,
ar_pci
->
features
))
if
(
!
test_bit
(
ATH10K_PCI_FEATURE_SOC_POWER_SAVE
,
ar_pci
->
features
))
...
@@ -2411,11 +2529,10 @@ static int ath10k_pci_init_irq(struct ath10k *ar)
...
@@ -2411,11 +2529,10 @@ static int ath10k_pci_init_irq(struct ath10k *ar)
/* Try MSI-X */
/* Try MSI-X */
if
(
ath10k_pci_irq_mode
==
ATH10K_PCI_IRQ_AUTO
&&
msix_supported
)
{
if
(
ath10k_pci_irq_mode
==
ATH10K_PCI_IRQ_AUTO
&&
msix_supported
)
{
ar_pci
->
num_msi_intrs
=
MSI_NUM_REQUEST
;
ar_pci
->
num_msi_intrs
=
MSI_NUM_REQUEST
;
ret
=
pci_enable_msi_block
(
ar_pci
->
pdev
,
ar_pci
->
num_msi_intrs
);
ret
=
pci_enable_msi_range
(
ar_pci
->
pdev
,
ar_pci
->
num_msi_intrs
,
if
(
ret
==
0
)
ar_pci
->
num_msi_intrs
);
return
0
;
if
(
ret
>
0
)
if
(
ret
>
0
)
pci_disable_msi
(
ar_pci
->
pdev
)
;
return
0
;
/* fall-through */
/* fall-through */
}
}
...
@@ -2482,6 +2599,8 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar)
...
@@ -2482,6 +2599,8 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar)
case
MSI_NUM_REQUEST
:
case
MSI_NUM_REQUEST
:
pci_disable_msi
(
ar_pci
->
pdev
);
pci_disable_msi
(
ar_pci
->
pdev
);
return
0
;
return
0
;
default:
pci_disable_msi
(
ar_pci
->
pdev
);
}
}
ath10k_warn
(
"unknown irq configuration upon deinit
\n
"
);
ath10k_warn
(
"unknown irq configuration upon deinit
\n
"
);
...
@@ -2523,7 +2642,7 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
...
@@ -2523,7 +2642,7 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
return
ret
;
return
ret
;
}
}
static
int
ath10k_pci_
device
_reset
(
struct
ath10k
*
ar
)
static
int
ath10k_pci_
cold
_reset
(
struct
ath10k
*
ar
)
{
{
int
i
,
ret
;
int
i
,
ret
;
u32
val
;
u32
val
;
...
...
drivers/net/wireless/ath/ath10k/txrx.c
View file @
9e4b4269
...
@@ -259,7 +259,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
...
@@ -259,7 +259,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
status
->
freq
=
ch
->
center_freq
;
status
->
freq
=
ch
->
center_freq
;
ath10k_dbg
(
ATH10K_DBG_DATA
,
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
\n
"
,
"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
,
info
->
skb
,
info
->
skb
->
len
,
info
->
skb
->
len
,
status
->
flag
==
0
?
"legacy"
:
""
,
status
->
flag
==
0
?
"legacy"
:
""
,
...
@@ -271,7 +271,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
...
@@ -271,7 +271,7 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
status
->
rate_idx
,
status
->
rate_idx
,
status
->
vht_nss
,
status
->
vht_nss
,
status
->
freq
,
status
->
freq
,
status
->
band
);
status
->
band
,
status
->
flag
,
info
->
fcs_err
);
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"rx skb: "
,
ath10k_dbg_dump
(
ATH10K_DBG_HTT_DUMP
,
NULL
,
"rx skb: "
,
info
->
skb
->
data
,
info
->
skb
->
len
);
info
->
skb
->
data
,
info
->
skb
->
len
);
...
...
drivers/net/wireless/ath/ath10k/wmi.c
View file @
9e4b4269
...
@@ -213,7 +213,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
...
@@ -213,7 +213,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
.
p2p_go_set_beacon_ie
=
WMI_10X_P2P_GO_SET_BEACON_IE
,
.
p2p_go_set_beacon_ie
=
WMI_10X_P2P_GO_SET_BEACON_IE
,
.
p2p_go_set_probe_resp_ie
=
WMI_10X_P2P_GO_SET_PROBE_RESP_IE
,
.
p2p_go_set_probe_resp_ie
=
WMI_10X_P2P_GO_SET_PROBE_RESP_IE
,
.
p2p_set_vendor_ie_data_cmdid
=
WMI_CMD_UNSUPPORTED
,
.
p2p_set_vendor_ie_data_cmdid
=
WMI_CMD_UNSUPPORTED
,
.
ap_ps_peer_param_cmdid
=
WMI_
CMD_UNSUPPORTE
D
,
.
ap_ps_peer_param_cmdid
=
WMI_
10X_AP_PS_PEER_PARAM_CMDI
D
,
.
ap_ps_peer_uapsd_coex_cmdid
=
WMI_CMD_UNSUPPORTED
,
.
ap_ps_peer_uapsd_coex_cmdid
=
WMI_CMD_UNSUPPORTED
,
.
peer_rate_retry_sched_cmdid
=
WMI_10X_PEER_RATE_RETRY_SCHED_CMDID
,
.
peer_rate_retry_sched_cmdid
=
WMI_10X_PEER_RATE_RETRY_SCHED_CMDID
,
.
wlan_profile_trigger_cmdid
=
WMI_10X_WLAN_PROFILE_TRIGGER_CMDID
,
.
wlan_profile_trigger_cmdid
=
WMI_10X_WLAN_PROFILE_TRIGGER_CMDID
,
...
@@ -420,7 +420,6 @@ static struct wmi_pdev_param_map wmi_pdev_param_map = {
...
@@ -420,7 +420,6 @@ static struct wmi_pdev_param_map wmi_pdev_param_map = {
.
bcnflt_stats_update_period
=
WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD
,
.
bcnflt_stats_update_period
=
WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD
,
.
pmf_qos
=
WMI_PDEV_PARAM_PMF_QOS
,
.
pmf_qos
=
WMI_PDEV_PARAM_PMF_QOS
,
.
arp_ac_override
=
WMI_PDEV_PARAM_ARP_AC_OVERRIDE
,
.
arp_ac_override
=
WMI_PDEV_PARAM_ARP_AC_OVERRIDE
,
.
arpdhcp_ac_override
=
WMI_PDEV_PARAM_UNSUPPORTED
,
.
dcs
=
WMI_PDEV_PARAM_DCS
,
.
dcs
=
WMI_PDEV_PARAM_DCS
,
.
ani_enable
=
WMI_PDEV_PARAM_ANI_ENABLE
,
.
ani_enable
=
WMI_PDEV_PARAM_ANI_ENABLE
,
.
ani_poll_period
=
WMI_PDEV_PARAM_ANI_POLL_PERIOD
,
.
ani_poll_period
=
WMI_PDEV_PARAM_ANI_POLL_PERIOD
,
...
@@ -472,8 +471,7 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
...
@@ -472,8 +471,7 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
.
bcnflt_stats_update_period
=
.
bcnflt_stats_update_period
=
WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD
,
WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD
,
.
pmf_qos
=
WMI_10X_PDEV_PARAM_PMF_QOS
,
.
pmf_qos
=
WMI_10X_PDEV_PARAM_PMF_QOS
,
.
arp_ac_override
=
WMI_PDEV_PARAM_UNSUPPORTED
,
.
arp_ac_override
=
WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE
,
.
arpdhcp_ac_override
=
WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE
,
.
dcs
=
WMI_10X_PDEV_PARAM_DCS
,
.
dcs
=
WMI_10X_PDEV_PARAM_DCS
,
.
ani_enable
=
WMI_10X_PDEV_PARAM_ANI_ENABLE
,
.
ani_enable
=
WMI_10X_PDEV_PARAM_ANI_ENABLE
,
.
ani_poll_period
=
WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD
,
.
ani_poll_period
=
WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD
,
...
@@ -561,7 +559,6 @@ static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
...
@@ -561,7 +559,6 @@ static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
static
void
ath10k_wmi_tx_beacon_nowait
(
struct
ath10k_vif
*
arvif
)
static
void
ath10k_wmi_tx_beacon_nowait
(
struct
ath10k_vif
*
arvif
)
{
{
struct
wmi_bcn_tx_arg
arg
=
{
0
};
int
ret
;
int
ret
;
lockdep_assert_held
(
&
arvif
->
ar
->
data_lock
);
lockdep_assert_held
(
&
arvif
->
ar
->
data_lock
);
...
@@ -569,18 +566,16 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
...
@@ -569,18 +566,16 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
if
(
arvif
->
beacon
==
NULL
)
if
(
arvif
->
beacon
==
NULL
)
return
;
return
;
arg
.
vdev_id
=
arvif
->
vdev_id
;
if
(
arvif
->
beacon_sent
)
arg
.
tx_rate
=
0
;
return
;
arg
.
tx_power
=
0
;
arg
.
bcn
=
arvif
->
beacon
->
data
;
arg
.
bcn_len
=
arvif
->
beacon
->
len
;
ret
=
ath10k_wmi_beacon_send_
nowait
(
arvif
->
ar
,
&
arg
);
ret
=
ath10k_wmi_beacon_send_
ref_nowait
(
arvif
);
if
(
ret
)
if
(
ret
)
return
;
return
;
dev_kfree_skb_any
(
arvif
->
beacon
);
/* We need to retain the arvif->beacon reference for DMA unmapping and
arvif
->
beacon
=
NULL
;
* freeing the skbuff later. */
arvif
->
beacon_sent
=
true
;
}
}
static
void
ath10k_wmi_tx_beacons_iter
(
void
*
data
,
u8
*
mac
,
static
void
ath10k_wmi_tx_beacons_iter
(
void
*
data
,
u8
*
mac
,
...
@@ -1116,7 +1111,27 @@ static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar,
...
@@ -1116,7 +1111,27 @@ static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar,
static
void
ath10k_wmi_event_peer_sta_kickout
(
struct
ath10k
*
ar
,
static
void
ath10k_wmi_event_peer_sta_kickout
(
struct
ath10k
*
ar
,
struct
sk_buff
*
skb
)
struct
sk_buff
*
skb
)
{
{
ath10k_dbg
(
ATH10K_DBG_WMI
,
"WMI_PEER_STA_KICKOUT_EVENTID
\n
"
);
struct
wmi_peer_sta_kickout_event
*
ev
;
struct
ieee80211_sta
*
sta
;
ev
=
(
struct
wmi_peer_sta_kickout_event
*
)
skb
->
data
;
ath10k_dbg
(
ATH10K_DBG_WMI
,
"wmi event peer sta kickout %pM
\n
"
,
ev
->
peer_macaddr
.
addr
);
rcu_read_lock
();
sta
=
ieee80211_find_sta_by_ifaddr
(
ar
->
hw
,
ev
->
peer_macaddr
.
addr
,
NULL
);
if
(
!
sta
)
{
ath10k_warn
(
"Spurious quick kickout for STA %pM
\n
"
,
ev
->
peer_macaddr
.
addr
);
goto
exit
;
}
ieee80211_report_low_ack
(
sta
,
10
);
exit:
rcu_read_unlock
();
}
}
/*
/*
...
@@ -1217,6 +1232,13 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
...
@@ -1217,6 +1232,13 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
tim
->
bitmap_ctrl
=
!!
__le32_to_cpu
(
bcn_info
->
tim_info
.
tim_mcast
);
tim
->
bitmap_ctrl
=
!!
__le32_to_cpu
(
bcn_info
->
tim_info
.
tim_mcast
);
memcpy
(
tim
->
virtual_map
,
arvif
->
u
.
ap
.
tim_bitmap
,
pvm_len
);
memcpy
(
tim
->
virtual_map
,
arvif
->
u
.
ap
.
tim_bitmap
,
pvm_len
);
if
(
tim
->
dtim_count
==
0
)
{
ATH10K_SKB_CB
(
bcn
)
->
bcn
.
dtim_zero
=
true
;
if
(
__le32_to_cpu
(
bcn_info
->
tim_info
.
tim_mcast
)
==
1
)
ATH10K_SKB_CB
(
bcn
)
->
bcn
.
deliver_cab
=
true
;
}
ath10k_dbg
(
ATH10K_DBG_MGMT
,
"dtim %d/%d mcast %d pvmlen %d
\n
"
,
ath10k_dbg
(
ATH10K_DBG_MGMT
,
"dtim %d/%d mcast %d pvmlen %d
\n
"
,
tim
->
dtim_count
,
tim
->
dtim_period
,
tim
->
dtim_count
,
tim
->
dtim_period
,
tim
->
bitmap_ctrl
,
pvm_len
);
tim
->
bitmap_ctrl
,
pvm_len
);
...
@@ -1385,6 +1407,17 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
...
@@ -1385,6 +1407,17 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
continue
;
continue
;
}
}
/* There are no completions for beacons so wait for next SWBA
* before telling mac80211 to decrement CSA counter
*
* Once CSA counter is completed stop sending beacons until
* actual channel switch is done */
if
(
arvif
->
vif
->
csa_active
&&
ieee80211_csa_is_complete
(
arvif
->
vif
))
{
ieee80211_csa_finish
(
arvif
->
vif
);
continue
;
}
bcn
=
ieee80211_beacon_get
(
ar
->
hw
,
arvif
->
vif
);
bcn
=
ieee80211_beacon_get
(
ar
->
hw
,
arvif
->
vif
);
if
(
!
bcn
)
{
if
(
!
bcn
)
{
ath10k_warn
(
"could not get mac80211 beacon
\n
"
);
ath10k_warn
(
"could not get mac80211 beacon
\n
"
);
...
@@ -1396,13 +1429,20 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
...
@@ -1396,13 +1429,20 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
ath10k_wmi_update_noa
(
ar
,
arvif
,
bcn
,
bcn_info
);
ath10k_wmi_update_noa
(
ar
,
arvif
,
bcn
,
bcn_info
);
spin_lock_bh
(
&
ar
->
data_lock
);
spin_lock_bh
(
&
ar
->
data_lock
);
if
(
arvif
->
beacon
)
{
if
(
arvif
->
beacon
)
{
ath10k_warn
(
"SWBA overrun on vdev %d
\n
"
,
if
(
!
arvif
->
beacon_sent
)
arvif
->
vdev_id
);
ath10k_warn
(
"SWBA overrun on vdev %d
\n
"
,
arvif
->
vdev_id
);
ath10k_skb_unmap
(
ar
->
dev
,
arvif
->
beacon
);
dev_kfree_skb_any
(
arvif
->
beacon
);
dev_kfree_skb_any
(
arvif
->
beacon
);
}
}
ath10k_skb_map
(
ar
->
dev
,
bcn
);
arvif
->
beacon
=
bcn
;
arvif
->
beacon
=
bcn
;
arvif
->
beacon_sent
=
false
;
ath10k_wmi_tx_beacon_nowait
(
arvif
);
ath10k_wmi_tx_beacon_nowait
(
arvif
);
spin_unlock_bh
(
&
ar
->
data_lock
);
spin_unlock_bh
(
&
ar
->
data_lock
);
...
@@ -2031,11 +2071,11 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
...
@@ -2031,11 +2071,11 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
memcpy
(
ar
->
mac_addr
,
ev
->
mac_addr
.
addr
,
ETH_ALEN
);
memcpy
(
ar
->
mac_addr
,
ev
->
mac_addr
.
addr
,
ETH_ALEN
);
ath10k_dbg
(
ATH10K_DBG_WMI
,
ath10k_dbg
(
ATH10K_DBG_WMI
,
"wmi event ready sw_version %u abi_version %u mac_addr %pM status %d
\n
"
,
"wmi event ready sw_version %u abi_version %u mac_addr %pM status %d
skb->len %i ev-sz %zu
\n
"
,
__le32_to_cpu
(
ev
->
sw_version
),
__le32_to_cpu
(
ev
->
sw_version
),
__le32_to_cpu
(
ev
->
abi_version
),
__le32_to_cpu
(
ev
->
abi_version
),
ev
->
mac_addr
.
addr
,
ev
->
mac_addr
.
addr
,
__le32_to_cpu
(
ev
->
status
));
__le32_to_cpu
(
ev
->
status
)
,
skb
->
len
,
sizeof
(
*
ev
)
);
complete
(
&
ar
->
wmi
.
unified_ready
);
complete
(
&
ar
->
wmi
.
unified_ready
);
return
0
;
return
0
;
...
@@ -2403,7 +2443,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
...
@@ -2403,7 +2443,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
ar
->
wmi
.
cmd
->
pdev_set_channel_cmdid
);
ar
->
wmi
.
cmd
->
pdev_set_channel_cmdid
);
}
}
int
ath10k_wmi_pdev_suspend_target
(
struct
ath10k
*
ar
)
int
ath10k_wmi_pdev_suspend_target
(
struct
ath10k
*
ar
,
u32
suspend_opt
)
{
{
struct
wmi_pdev_suspend_cmd
*
cmd
;
struct
wmi_pdev_suspend_cmd
*
cmd
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
...
@@ -2413,7 +2453,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
...
@@ -2413,7 +2453,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
return
-
ENOMEM
;
return
-
ENOMEM
;
cmd
=
(
struct
wmi_pdev_suspend_cmd
*
)
skb
->
data
;
cmd
=
(
struct
wmi_pdev_suspend_cmd
*
)
skb
->
data
;
cmd
->
suspend_opt
=
WMI_PDEV_SUSPEND
;
cmd
->
suspend_opt
=
__cpu_to_le32
(
suspend_opt
)
;
return
ath10k_wmi_cmd_send
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
pdev_suspend_cmdid
);
return
ath10k_wmi_cmd_send
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
pdev_suspend_cmdid
);
}
}
...
@@ -3411,25 +3451,41 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
...
@@ -3411,25 +3451,41 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
return
ath10k_wmi_cmd_send
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
peer_assoc_cmdid
);
return
ath10k_wmi_cmd_send
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
peer_assoc_cmdid
);
}
}
int
ath10k_wmi_beacon_send_nowait
(
struct
ath10k
*
ar
,
/* This function assumes the beacon is already DMA mapped */
const
struct
wmi_bcn_tx_arg
*
arg
)
int
ath10k_wmi_beacon_send_ref_nowait
(
struct
ath10k_vif
*
arvif
)
{
{
struct
wmi_bcn_tx_cmd
*
cmd
;
struct
wmi_bcn_tx_
ref_
cmd
*
cmd
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
struct
sk_buff
*
beacon
=
arvif
->
beacon
;
struct
ath10k
*
ar
=
arvif
->
ar
;
struct
ieee80211_hdr
*
hdr
;
int
ret
;
int
ret
;
u16
fc
;
skb
=
ath10k_wmi_alloc_skb
(
sizeof
(
*
cmd
)
+
arg
->
bcn_len
);
skb
=
ath10k_wmi_alloc_skb
(
sizeof
(
*
cmd
));
if
(
!
skb
)
if
(
!
skb
)
return
-
ENOMEM
;
return
-
ENOMEM
;
cmd
=
(
struct
wmi_bcn_tx_cmd
*
)
skb
->
data
;
hdr
=
(
struct
ieee80211_hdr
*
)
beacon
->
data
;
cmd
->
hdr
.
vdev_id
=
__cpu_to_le32
(
arg
->
vdev_id
);
fc
=
le16_to_cpu
(
hdr
->
frame_control
);
cmd
->
hdr
.
tx_rate
=
__cpu_to_le32
(
arg
->
tx_rate
);
cmd
->
hdr
.
tx_power
=
__cpu_to_le32
(
arg
->
tx_power
);
cmd
=
(
struct
wmi_bcn_tx_ref_cmd
*
)
skb
->
data
;
cmd
->
hdr
.
bcn_len
=
__cpu_to_le32
(
arg
->
bcn_len
);
cmd
->
vdev_id
=
__cpu_to_le32
(
arvif
->
vdev_id
);
memcpy
(
cmd
->
bcn
,
arg
->
bcn
,
arg
->
bcn_len
);
cmd
->
data_len
=
__cpu_to_le32
(
beacon
->
len
);
cmd
->
data_ptr
=
__cpu_to_le32
(
ATH10K_SKB_CB
(
beacon
)
->
paddr
);
cmd
->
msdu_id
=
0
;
cmd
->
frame_control
=
__cpu_to_le32
(
fc
);
cmd
->
flags
=
0
;
if
(
ATH10K_SKB_CB
(
beacon
)
->
bcn
.
dtim_zero
)
cmd
->
flags
|=
__cpu_to_le32
(
WMI_BCN_TX_REF_FLAG_DTIM_ZERO
);
if
(
ATH10K_SKB_CB
(
beacon
)
->
bcn
.
deliver_cab
)
cmd
->
flags
|=
__cpu_to_le32
(
WMI_BCN_TX_REF_FLAG_DELIVER_CAB
);
ret
=
ath10k_wmi_cmd_send_nowait
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
pdev_send_bcn_cmdid
);
ret
=
ath10k_wmi_cmd_send_nowait
(
ar
,
skb
,
ar
->
wmi
.
cmd
->
bcn_tx_cmdid
);
if
(
ret
)
if
(
ret
)
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
...
...
drivers/net/wireless/ath/ath10k/wmi.h
View file @
9e4b4269
...
@@ -2277,7 +2277,6 @@ struct wmi_pdev_param_map {
...
@@ -2277,7 +2277,6 @@ struct wmi_pdev_param_map {
u32
bcnflt_stats_update_period
;
u32
bcnflt_stats_update_period
;
u32
pmf_qos
;
u32
pmf_qos
;
u32
arp_ac_override
;
u32
arp_ac_override
;
u32
arpdhcp_ac_override
;
u32
dcs
;
u32
dcs
;
u32
ani_enable
;
u32
ani_enable
;
u32
ani_poll_period
;
u32
ani_poll_period
;
...
@@ -3403,6 +3402,24 @@ struct wmi_bcn_tx_arg {
...
@@ -3403,6 +3402,24 @@ struct wmi_bcn_tx_arg {
const
void
*
bcn
;
const
void
*
bcn
;
};
};
enum
wmi_bcn_tx_ref_flags
{
WMI_BCN_TX_REF_FLAG_DTIM_ZERO
=
0x1
,
WMI_BCN_TX_REF_FLAG_DELIVER_CAB
=
0x2
,
};
struct
wmi_bcn_tx_ref_cmd
{
__le32
vdev_id
;
__le32
data_len
;
/* physical address of the frame - dma pointer */
__le32
data_ptr
;
/* id for host to track */
__le32
msdu_id
;
/* frame ctrl to setup PPDU desc */
__le32
frame_control
;
/* to control CABQ traffic: WMI_BCN_TX_REF_FLAG_ */
__le32
flags
;
}
__packed
;
/* Beacon filter */
/* Beacon filter */
#define WMI_BCN_FILTER_ALL 0
/* Filter all beacons */
#define WMI_BCN_FILTER_ALL 0
/* Filter all beacons */
#define WMI_BCN_FILTER_NONE 1
/* Pass all beacons */
#define WMI_BCN_FILTER_NONE 1
/* Pass all beacons */
...
@@ -3859,6 +3876,12 @@ enum wmi_peer_smps_state {
...
@@ -3859,6 +3876,12 @@ enum wmi_peer_smps_state {
WMI_PEER_SMPS_DYNAMIC
=
0x2
WMI_PEER_SMPS_DYNAMIC
=
0x2
};
};
enum
wmi_peer_chwidth
{
WMI_PEER_CHWIDTH_20MHZ
=
0
,
WMI_PEER_CHWIDTH_40MHZ
=
1
,
WMI_PEER_CHWIDTH_80MHZ
=
2
,
};
enum
wmi_peer_param
{
enum
wmi_peer_param
{
WMI_PEER_SMPS_STATE
=
0x1
,
/* see %wmi_peer_smps_state */
WMI_PEER_SMPS_STATE
=
0x1
,
/* see %wmi_peer_smps_state */
WMI_PEER_AMPDU
=
0x2
,
WMI_PEER_AMPDU
=
0x2
,
...
@@ -4039,6 +4062,10 @@ struct wmi_chan_info_event {
...
@@ -4039,6 +4062,10 @@ struct wmi_chan_info_event {
__le32
cycle_count
;
__le32
cycle_count
;
}
__packed
;
}
__packed
;
struct
wmi_peer_sta_kickout_event
{
struct
wmi_mac_addr
peer_macaddr
;
}
__packed
;
#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
/* FIXME: empirically extrapolated */
/* FIXME: empirically extrapolated */
...
@@ -4172,7 +4199,7 @@ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
...
@@ -4172,7 +4199,7 @@ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
int
ath10k_wmi_connect_htc_service
(
struct
ath10k
*
ar
);
int
ath10k_wmi_connect_htc_service
(
struct
ath10k
*
ar
);
int
ath10k_wmi_pdev_set_channel
(
struct
ath10k
*
ar
,
int
ath10k_wmi_pdev_set_channel
(
struct
ath10k
*
ar
,
const
struct
wmi_channel_arg
*
);
const
struct
wmi_channel_arg
*
);
int
ath10k_wmi_pdev_suspend_target
(
struct
ath10k
*
ar
);
int
ath10k_wmi_pdev_suspend_target
(
struct
ath10k
*
ar
,
u32
suspend_opt
);
int
ath10k_wmi_pdev_resume_target
(
struct
ath10k
*
ar
);
int
ath10k_wmi_pdev_resume_target
(
struct
ath10k
*
ar
);
int
ath10k_wmi_pdev_set_regdomain
(
struct
ath10k
*
ar
,
u16
rd
,
u16
rd2g
,
int
ath10k_wmi_pdev_set_regdomain
(
struct
ath10k
*
ar
,
u16
rd
,
u16
rd2g
,
u16
rd5g
,
u16
ctl2g
,
u16
ctl5g
);
u16
rd5g
,
u16
ctl2g
,
u16
ctl5g
);
...
@@ -4219,8 +4246,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
...
@@ -4219,8 +4246,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
enum
wmi_ap_ps_peer_param
param_id
,
u32
value
);
enum
wmi_ap_ps_peer_param
param_id
,
u32
value
);
int
ath10k_wmi_scan_chan_list
(
struct
ath10k
*
ar
,
int
ath10k_wmi_scan_chan_list
(
struct
ath10k
*
ar
,
const
struct
wmi_scan_chan_list_arg
*
arg
);
const
struct
wmi_scan_chan_list_arg
*
arg
);
int
ath10k_wmi_beacon_send_nowait
(
struct
ath10k
*
ar
,
int
ath10k_wmi_beacon_send_ref_nowait
(
struct
ath10k_vif
*
arvif
);
const
struct
wmi_bcn_tx_arg
*
arg
);
int
ath10k_wmi_pdev_set_wmm_params
(
struct
ath10k
*
ar
,
int
ath10k_wmi_pdev_set_wmm_params
(
struct
ath10k
*
ar
,
const
struct
wmi_pdev_set_wmm_params_arg
*
arg
);
const
struct
wmi_pdev_set_wmm_params_arg
*
arg
);
int
ath10k_wmi_request_stats
(
struct
ath10k
*
ar
,
enum
wmi_stats_id
stats_id
);
int
ath10k_wmi_request_stats
(
struct
ath10k
*
ar
,
enum
wmi_stats_id
stats_id
);
...
...
drivers/net/wireless/ath/ath6kl/usb.c
View file @
9e4b4269
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
/* constants */
/* constants */
#define TX_URB_COUNT 32
#define TX_URB_COUNT 32
#define RX_URB_COUNT 32
#define RX_URB_COUNT 32
#define ATH6KL_USB_RX_BUFFER_SIZE
1700
#define ATH6KL_USB_RX_BUFFER_SIZE
4096
/* tx/rx pipes for usb */
/* tx/rx pipes for usb */
enum
ATH6KL_USB_PIPE_ID
{
enum
ATH6KL_USB_PIPE_ID
{
...
@@ -481,8 +481,8 @@ static void ath6kl_usb_start_recv_pipes(struct ath6kl_usb *ar_usb)
...
@@ -481,8 +481,8 @@ static void ath6kl_usb_start_recv_pipes(struct ath6kl_usb *ar_usb)
* ATH6KL_USB_RX_BUFFER_SIZE);
* ATH6KL_USB_RX_BUFFER_SIZE);
*/
*/
ar_usb
->
pipes
[
ATH6KL_USB_PIPE_RX_DATA
].
urb_cnt_thresh
=
ar_usb
->
pipes
[
ATH6KL_USB_PIPE_RX_DATA
].
urb_cnt_thresh
=
1
;
ar_usb
->
pipes
[
ATH6KL_USB_PIPE_RX_DATA
].
urb_alloc
/
2
;
ath6kl_usb_post_recv_transfers
(
&
ar_usb
->
pipes
[
ATH6KL_USB_PIPE_RX_DATA
],
ath6kl_usb_post_recv_transfers
(
&
ar_usb
->
pipes
[
ATH6KL_USB_PIPE_RX_DATA
],
ATH6KL_USB_RX_BUFFER_SIZE
);
ATH6KL_USB_RX_BUFFER_SIZE
);
}
}
...
...
drivers/net/wireless/ath/ath6kl/wmi.c
View file @
9e4b4269
...
@@ -914,7 +914,7 @@ ath6kl_get_regpair(u16 regdmn)
...
@@ -914,7 +914,7 @@ ath6kl_get_regpair(u16 regdmn)
return
NULL
;
return
NULL
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regDomainPairs
);
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regDomainPairs
);
i
++
)
{
if
(
regDomainPairs
[
i
].
reg
DmnEnum
==
regdmn
)
if
(
regDomainPairs
[
i
].
reg
_domain
==
regdmn
)
return
&
regDomainPairs
[
i
];
return
&
regDomainPairs
[
i
];
}
}
...
@@ -954,7 +954,7 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
...
@@ -954,7 +954,7 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
country
=
ath6kl_regd_find_country_by_rd
((
u16
)
reg_code
);
country
=
ath6kl_regd_find_country_by_rd
((
u16
)
reg_code
);
if
(
regpair
)
if
(
regpair
)
ath6kl_dbg
(
ATH6KL_DBG_WMI
,
"Regpair used: 0x%0x
\n
"
,
ath6kl_dbg
(
ATH6KL_DBG_WMI
,
"Regpair used: 0x%0x
\n
"
,
regpair
->
reg
DmnEnum
);
regpair
->
reg
_domain
);
else
else
ath6kl_warn
(
"Regpair not found reg_code 0x%0x
\n
"
,
ath6kl_warn
(
"Regpair not found reg_code 0x%0x
\n
"
,
reg_code
);
reg_code
);
...
...
drivers/net/wireless/ath/regd.c
View file @
9e4b4269
...
@@ -222,7 +222,7 @@ static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
...
@@ -222,7 +222,7 @@ static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
static
const
struct
static
const
struct
ieee80211_regdomain
*
ath_world_regdomain
(
struct
ath_regulatory
*
reg
)
ieee80211_regdomain
*
ath_world_regdomain
(
struct
ath_regulatory
*
reg
)
{
{
switch
(
reg
->
regpair
->
reg
DmnEnum
)
{
switch
(
reg
->
regpair
->
reg
_domain
)
{
case
0x60
:
case
0x60
:
case
0x61
:
case
0x61
:
case
0x62
:
case
0x62
:
...
@@ -431,7 +431,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
...
@@ -431,7 +431,7 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
enum
nl80211_reg_initiator
initiator
,
enum
nl80211_reg_initiator
initiator
,
struct
ath_regulatory
*
reg
)
struct
ath_regulatory
*
reg
)
{
{
switch
(
reg
->
regpair
->
reg
DmnEnum
)
{
switch
(
reg
->
regpair
->
reg
_domain
)
{
case
0x60
:
case
0x60
:
case
0x63
:
case
0x63
:
case
0x66
:
case
0x66
:
...
@@ -560,7 +560,7 @@ static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
...
@@ -560,7 +560,7 @@ static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
printk
(
KERN_DEBUG
"ath: EEPROM indicates we "
printk
(
KERN_DEBUG
"ath: EEPROM indicates we "
"should expect a direct regpair map
\n
"
);
"should expect a direct regpair map
\n
"
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regDomainPairs
);
i
++
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regDomainPairs
);
i
++
)
if
(
regDomainPairs
[
i
].
reg
DmnEnum
==
rd
)
if
(
regDomainPairs
[
i
].
reg
_domain
==
rd
)
return
true
;
return
true
;
}
}
printk
(
KERN_DEBUG
printk
(
KERN_DEBUG
...
@@ -617,7 +617,7 @@ ath_get_regpair(int regdmn)
...
@@ -617,7 +617,7 @@ ath_get_regpair(int regdmn)
if
(
regdmn
==
NO_ENUMRD
)
if
(
regdmn
==
NO_ENUMRD
)
return
NULL
;
return
NULL
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regDomainPairs
);
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regDomainPairs
);
i
++
)
{
if
(
regDomainPairs
[
i
].
reg
DmnEnum
==
regdmn
)
if
(
regDomainPairs
[
i
].
reg
_domain
==
regdmn
)
return
&
regDomainPairs
[
i
];
return
&
regDomainPairs
[
i
];
}
}
return
NULL
;
return
NULL
;
...
@@ -741,7 +741,7 @@ static int __ath_regd_init(struct ath_regulatory *reg)
...
@@ -741,7 +741,7 @@ static int __ath_regd_init(struct ath_regulatory *reg)
printk
(
KERN_DEBUG
"ath: Country alpha2 being used: %c%c
\n
"
,
printk
(
KERN_DEBUG
"ath: Country alpha2 being used: %c%c
\n
"
,
reg
->
alpha2
[
0
],
reg
->
alpha2
[
1
]);
reg
->
alpha2
[
0
],
reg
->
alpha2
[
1
]);
printk
(
KERN_DEBUG
"ath: Regpair used: 0x%0x
\n
"
,
printk
(
KERN_DEBUG
"ath: Regpair used: 0x%0x
\n
"
,
reg
->
regpair
->
reg
DmnEnum
);
reg
->
regpair
->
reg
_domain
);
return
0
;
return
0
;
}
}
...
...
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