Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
76015021
Commit
76015021
authored
Jun 10, 2013
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
parents
f7a01cac
fded313e
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
371 additions
and
66 deletions
+371
-66
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
+2
-2
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-trans.h
+8
-6
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+1
-1
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/d3.c
+139
-10
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
+1
-0
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+7
-1
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+5
-1
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+9
-26
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+4
-0
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/ops.c
+5
-4
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+2
-1
drivers/net/wireless/iwlwifi/mvm/power.c
drivers/net/wireless/iwlwifi/mvm/power.c
+13
-0
drivers/net/wireless/iwlwifi/mvm/quota.c
drivers/net/wireless/iwlwifi/mvm/quota.c
+16
-9
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rs.c
+114
-1
drivers/net/wireless/iwlwifi/mvm/rs.h
drivers/net/wireless/iwlwifi/mvm/rs.h
+12
-0
drivers/net/wireless/iwlwifi/mvm/tt.c
drivers/net/wireless/iwlwifi/mvm/tt.c
+3
-0
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+1
-1
drivers/net/wireless/iwlwifi/mvm/utils.c
drivers/net/wireless/iwlwifi/mvm/utils.c
+10
-0
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+17
-2
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+2
-1
No files found.
drivers/net/wireless/iwlwifi/dvm/mac80211.c
View file @
76015021
...
...
@@ -430,7 +430,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
iwl_write32
(
priv
->
trans
,
CSR_UCODE_DRV_GP1_SET
,
CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE
);
iwl_trans_d3_suspend
(
priv
->
trans
);
iwl_trans_d3_suspend
(
priv
->
trans
,
false
);
goto
out
;
...
...
@@ -504,7 +504,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
/* we'll clear ctx->vif during iwlagn_prepare_restart() */
vif
=
ctx
->
vif
;
ret
=
iwl_trans_d3_resume
(
priv
->
trans
,
&
d3_status
);
ret
=
iwl_trans_d3_resume
(
priv
->
trans
,
&
d3_status
,
false
);
if
(
ret
)
goto
out_unlock
;
...
...
drivers/net/wireless/iwlwifi/iwl-trans.h
View file @
76015021
...
...
@@ -428,8 +428,9 @@ struct iwl_trans_ops {
void
(
*
fw_alive
)(
struct
iwl_trans
*
trans
,
u32
scd_addr
);
void
(
*
stop_device
)(
struct
iwl_trans
*
trans
);
void
(
*
d3_suspend
)(
struct
iwl_trans
*
trans
);
int
(
*
d3_resume
)(
struct
iwl_trans
*
trans
,
enum
iwl_d3_status
*
status
);
void
(
*
d3_suspend
)(
struct
iwl_trans
*
trans
,
bool
test
);
int
(
*
d3_resume
)(
struct
iwl_trans
*
trans
,
enum
iwl_d3_status
*
status
,
bool
test
);
int
(
*
send_cmd
)(
struct
iwl_trans
*
trans
,
struct
iwl_host_cmd
*
cmd
);
...
...
@@ -588,17 +589,18 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans)
trans
->
state
=
IWL_TRANS_NO_FW
;
}
static
inline
void
iwl_trans_d3_suspend
(
struct
iwl_trans
*
trans
)
static
inline
void
iwl_trans_d3_suspend
(
struct
iwl_trans
*
trans
,
bool
test
)
{
might_sleep
();
trans
->
ops
->
d3_suspend
(
trans
);
trans
->
ops
->
d3_suspend
(
trans
,
test
);
}
static
inline
int
iwl_trans_d3_resume
(
struct
iwl_trans
*
trans
,
enum
iwl_d3_status
*
status
)
enum
iwl_d3_status
*
status
,
bool
test
)
{
might_sleep
();
return
trans
->
ops
->
d3_resume
(
trans
,
status
);
return
trans
->
ops
->
d3_resume
(
trans
,
status
,
test
);
}
static
inline
int
iwl_trans_send_cmd
(
struct
iwl_trans
*
trans
,
...
...
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
View file @
76015021
...
...
@@ -174,7 +174,7 @@ static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = {
static
const
__le32
iwl_loose_lookup
[
BT_COEX_LUT_SIZE
]
=
{
cpu_to_le32
(
0xaaaaaaaa
),
cpu_to_le32
(
0xaaaaaaaa
),
cpu_to_le32
(
0xa
e
aaaaaa
),
cpu_to_le32
(
0xa
a
aaaaaa
),
cpu_to_le32
(
0xaaaaaaaa
),
cpu_to_le32
(
0xcc00ff28
),
cpu_to_le32
(
0x0000aaaa
),
...
...
drivers/net/wireless/iwlwifi/mvm/d3.c
View file @
76015021
...
...
@@ -63,6 +63,7 @@
#include <linux/etherdevice.h>
#include <linux/ip.h>
#include <linux/fs.h>
#include <net/cfg80211.h>
#include <net/ipv6.h>
#include <net/tcp.h>
...
...
@@ -756,7 +757,9 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return
0
;
}
int
iwl_mvm_suspend
(
struct
ieee80211_hw
*
hw
,
struct
cfg80211_wowlan
*
wowlan
)
static
int
__iwl_mvm_suspend
(
struct
ieee80211_hw
*
hw
,
struct
cfg80211_wowlan
*
wowlan
,
bool
test
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_d3_iter_data
suspend_iter_data
=
{
...
...
@@ -769,7 +772,7 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
struct
iwl_wowlan_config_cmd
wowlan_config_cmd
=
{};
struct
iwl_wowlan_kek_kck_material_cmd
kek_kck_cmd
=
{};
struct
iwl_wowlan_tkip_params_cmd
tkip_cmd
=
{};
struct
iwl_d3_manager_config
d3_cfg_cmd
=
{
struct
iwl_d3_manager_config
d3_cfg_cmd
_data
=
{
/*
* Program the minimum sleep time to 10 seconds, as many
* platforms have issues processing a wakeup signal while
...
...
@@ -777,17 +780,30 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
*/
.
min_sleep_time
=
cpu_to_le32
(
10
*
1000
*
1000
),
};
struct
iwl_host_cmd
d3_cfg_cmd
=
{
.
id
=
D3_CONFIG_CMD
,
.
flags
=
CMD_SYNC
|
CMD_WANT_SKB
,
.
data
[
0
]
=
&
d3_cfg_cmd_data
,
.
len
[
0
]
=
sizeof
(
d3_cfg_cmd_data
),
};
struct
wowlan_key_data
key_data
=
{
.
use_rsc_tsc
=
false
,
.
tkip
=
&
tkip_cmd
,
.
use_tkip
=
false
,
};
int
ret
,
i
;
int
len
__maybe_unused
;
u16
seq
;
u8
old_aux_sta_id
,
old_ap_sta_id
=
IWL_MVM_STATION_COUNT
;
if
(
WARN_ON
(
!
wowlan
))
if
(
!
wowlan
)
{
/*
* mac80211 shouldn't get here, but for D3 test
* it doesn't warrant a warning
*/
WARN_ON
(
!
test
);
return
-
EINVAL
;
}
key_data
.
rsc_tsc
=
kzalloc
(
sizeof
(
*
key_data
.
rsc_tsc
),
GFP_KERNEL
);
if
(
!
key_data
.
rsc_tsc
)
...
...
@@ -1012,14 +1028,26 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
goto
out
;
/* must be last -- this switches firmware state */
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
D3_CONFIG_CMD
,
CMD_SYNC
,
sizeof
(
d3_cfg_cmd
),
&
d3_cfg_cmd
);
ret
=
iwl_mvm_send_cmd
(
mvm
,
&
d3_cfg_cmd
);
if
(
ret
)
goto
out
;
#ifdef CONFIG_IWLWIFI_DEBUGFS
len
=
le32_to_cpu
(
d3_cfg_cmd
.
resp_pkt
->
len_n_flags
)
&
FH_RSCSR_FRAME_SIZE_MSK
;
if
(
len
>=
sizeof
(
u32
)
*
2
)
{
mvm
->
d3_test_pme_ptr
=
le32_to_cpup
((
__le32
*
)
d3_cfg_cmd
.
resp_pkt
->
data
);
}
else
if
(
test
)
{
/* in test mode we require the pointer */
ret
=
-
EIO
;
goto
out
;
}
#endif
iwl_free_resp
(
&
d3_cfg_cmd
);
clear_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
);
iwl_trans_d3_suspend
(
mvm
->
trans
);
iwl_trans_d3_suspend
(
mvm
->
trans
,
test
);
out:
mvm
->
aux_sta
.
sta_id
=
old_aux_sta_id
;
mvm_ap_sta
->
sta_id
=
old_ap_sta_id
;
...
...
@@ -1034,6 +1062,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
return
ret
;
}
int
iwl_mvm_suspend
(
struct
ieee80211_hw
*
hw
,
struct
cfg80211_wowlan
*
wowlan
)
{
return
__iwl_mvm_suspend
(
hw
,
wowlan
,
false
);
}
static
void
iwl_mvm_query_wakeup_reasons
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
...
...
@@ -1238,9 +1271,8 @@ static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
#endif
}
int
iwl_mvm_resume
(
struct
ieee80211_hw
*
hw
)
static
int
__iwl_mvm_resume
(
struct
iwl_mvm
*
mvm
,
bool
test
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_d3_iter_data
resume_iter_data
=
{
.
mvm
=
mvm
,
};
...
...
@@ -1260,7 +1292,7 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
vif
=
resume_iter_data
.
vif
;
ret
=
iwl_trans_d3_resume
(
mvm
->
trans
,
&
d3_status
);
ret
=
iwl_trans_d3_resume
(
mvm
->
trans
,
&
d3_status
,
test
);
if
(
ret
)
goto
out_unlock
;
...
...
@@ -1277,7 +1309,7 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
out_unlock:
mutex_unlock
(
&
mvm
->
mutex
);
if
(
vif
)
if
(
!
test
&&
vif
)
ieee80211_resume_disconnect
(
vif
);
/* return 1 to reconfigure the device */
...
...
@@ -1285,9 +1317,106 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
return
1
;
}
int
iwl_mvm_resume
(
struct
ieee80211_hw
*
hw
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
return
__iwl_mvm_resume
(
mvm
,
false
);
}
void
iwl_mvm_set_wakeup
(
struct
ieee80211_hw
*
hw
,
bool
enabled
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
device_set_wakeup_enable
(
mvm
->
trans
->
dev
,
enabled
);
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
static
int
iwl_mvm_d3_test_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
iwl_mvm
*
mvm
=
inode
->
i_private
;
int
err
;
if
(
mvm
->
d3_test_active
)
return
-
EBUSY
;
file
->
private_data
=
inode
->
i_private
;
ieee80211_stop_queues
(
mvm
->
hw
);
synchronize_net
();
/* start pseudo D3 */
rtnl_lock
();
err
=
__iwl_mvm_suspend
(
mvm
->
hw
,
mvm
->
hw
->
wiphy
->
wowlan_config
,
true
);
rtnl_unlock
();
if
(
err
>
0
)
err
=
-
EINVAL
;
if
(
err
)
{
ieee80211_wake_queues
(
mvm
->
hw
);
return
err
;
}
mvm
->
d3_test_active
=
true
;
return
0
;
}
static
ssize_t
iwl_mvm_d3_test_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_mvm
*
mvm
=
file
->
private_data
;
u32
pme_asserted
;
while
(
true
)
{
pme_asserted
=
iwl_trans_read_mem32
(
mvm
->
trans
,
mvm
->
d3_test_pme_ptr
);
if
(
pme_asserted
)
break
;
if
(
msleep_interruptible
(
100
))
break
;
}
return
0
;
}
static
void
iwl_mvm_d3_test_disconn_work_iter
(
void
*
_data
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
)
{
if
(
vif
->
type
==
NL80211_IFTYPE_STATION
)
ieee80211_connection_loss
(
vif
);
}
static
int
iwl_mvm_d3_test_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
iwl_mvm
*
mvm
=
inode
->
i_private
;
int
remaining_time
=
10
;
mvm
->
d3_test_active
=
false
;
__iwl_mvm_resume
(
mvm
,
true
);
iwl_abort_notification_waits
(
&
mvm
->
notif_wait
);
ieee80211_restart_hw
(
mvm
->
hw
);
/* wait for restart and disconnect all interfaces */
while
(
test_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
)
&&
remaining_time
>
0
)
{
remaining_time
--
;
msleep
(
1000
);
}
if
(
remaining_time
==
0
)
IWL_ERR
(
mvm
,
"Timed out waiting for HW restart to finish!
\n
"
);
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_d3_test_disconn_work_iter
,
NULL
);
ieee80211_wake_queues
(
mvm
->
hw
);
return
0
;
}
const
struct
file_operations
iwl_dbgfs_d3_test_ops
=
{
.
llseek
=
no_llseek
,
.
open
=
iwl_mvm_d3_test_open
,
.
read
=
iwl_mvm_d3_test_read
,
.
release
=
iwl_mvm_d3_test_release
,
};
#endif
drivers/net/wireless/iwlwifi/mvm/debugfs.c
View file @
76015021
...
...
@@ -938,6 +938,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE
(
fw_restart
,
mvm
->
debugfs_dir
,
S_IWUSR
);
#ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_ADD_FILE
(
d3_sram
,
mvm
->
debugfs_dir
,
S_IRUSR
|
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
d3_test
,
mvm
->
debugfs_dir
,
S_IRUSR
);
#endif
/*
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
View file @
76015021
...
...
@@ -71,7 +71,13 @@
#define MAC_INDEX_MIN_DRIVER 0
#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX
#define AC_NUM 4
/* Number of access categories */
enum
iwl_ac
{
AC_BK
,
AC_BE
,
AC_VI
,
AC_VO
,
AC_NUM
,
};
/**
* enum iwl_mac_protection_flags - MAC context flags
...
...
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
View file @
76015021
...
...
@@ -365,7 +365,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
break
;
case
NL80211_IFTYPE_AP
:
iwl_trans_ac_txq_enable
(
mvm
->
trans
,
vif
->
cab_queue
,
IWL_MVM_TX_FIFO_
VO
);
IWL_MVM_TX_FIFO_
MCAST
);
/* fall through */
default:
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
...
...
@@ -553,6 +553,10 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
cmd
->
ac
[
i
].
fifos_mask
=
BIT
(
iwl_mvm_ac_to_tx_fifo
[
i
]);
}
/* in AP mode, the MCAST FIFO takes the EDCA params from VO */
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
cmd
->
ac
[
AC_VO
].
fifos_mask
|=
BIT
(
IWL_MVM_TX_FIFO_MCAST
);
if
(
vif
->
bss_conf
.
qos
)
cmd
->
qos_flags
|=
cpu_to_le32
(
MAC_QOS_FLG_UPDATE_EDCA
);
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
View file @
76015021
...
...
@@ -609,21 +609,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
mvmvif
->
phy_ctxt
=
NULL
;
iwl_mvm_mac_ctxt_remove
(
mvm
,
vif
);
out_release:
/*
* TODO: remove this temporary code.
* Currently MVM FW supports power management only on single MAC.
* Check if only one additional interface remains after releasing
* current one. Update power mode on the remaining interface.
*/
if
(
vif
->
type
!=
NL80211_IFTYPE_P2P_DEVICE
)
mvm
->
vif_count
--
;
IWL_DEBUG_MAC80211
(
mvm
,
"Currently %d interfaces active
\n
"
,
mvm
->
vif_count
);
if
(
mvm
->
vif_count
==
1
)
{
ieee80211_iterate_active_interfaces
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_power_update_iterator
,
mvm
);
}
ieee80211_iterate_active_interfaces
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_power_update_iterator
,
mvm
);
iwl_mvm_mac_ctxt_release
(
mvm
,
vif
);
out_unlock:
mutex_unlock
(
&
mvm
->
mutex
);
...
...
@@ -785,6 +775,9 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
if
(
ret
)
IWL_ERR
(
mvm
,
"failed to update quotas
\n
"
);
}
ret
=
iwl_mvm_power_update_mode
(
mvm
,
vif
);
if
(
ret
)
IWL_ERR
(
mvm
,
"failed to update power mode
\n
"
);
}
else
if
(
changes
&
BSS_CHANGED_DTIM_PERIOD
)
{
/*
* We received a beacon _after_ association so
...
...
@@ -793,19 +786,9 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
iwl_mvm_remove_time_event
(
mvm
,
mvmvif
,
&
mvmvif
->
time_event_data
);
}
else
if
(
changes
&
BSS_CHANGED_PS
)
{
/*
* TODO: remove this temporary code.
* Currently MVM FW supports power management only on single
* MAC. Avoid power mode update if more than one interface
* is active.
*/
IWL_DEBUG_MAC80211
(
mvm
,
"Currently %d interfaces active
\n
"
,
mvm
->
vif_count
);
if
(
mvm
->
vif_count
==
1
)
{
ret
=
iwl_mvm_power_update_mode
(
mvm
,
vif
);
if
(
ret
)
IWL_ERR
(
mvm
,
"failed to update power mode
\n
"
);
}
ret
=
iwl_mvm_power_update_mode
(
mvm
,
vif
);
if
(
ret
)
IWL_ERR
(
mvm
,
"failed to update power mode
\n
"
);
}
}
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
View file @
76015021
...
...
@@ -88,6 +88,7 @@ enum iwl_mvm_tx_fifo {
IWL_MVM_TX_FIFO_BE
,
IWL_MVM_TX_FIFO_VI
,
IWL_MVM_TX_FIFO_VO
,
IWL_MVM_TX_FIFO_MCAST
=
5
,
};
extern
struct
ieee80211_ops
iwl_mvm_hw_ops
;
...
...
@@ -459,8 +460,10 @@ struct iwl_mvm {
#ifdef CONFIG_PM_SLEEP
int
gtk_ivlen
,
gtk_icvlen
,
ptk_ivlen
,
ptk_icvlen
;
#ifdef CONFIG_IWLWIFI_DEBUGFS
bool
d3_test_active
;
bool
store_d3_resume_sram
;
void
*
d3_resume_sram
;
u32
d3_test_pme_ptr
;
#endif
#endif
...
...
@@ -669,6 +672,7 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
struct
inet6_dev
*
idev
);
void
iwl_mvm_set_default_unicast_key
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
int
idx
);
extern
const
struct
file_operations
iwl_dbgfs_d3_test_ops
;
/* BT Coex */
int
iwl_send_bt_prio_tbl
(
struct
iwl_mvm
*
mvm
);
...
...
drivers/net/wireless/iwlwifi/mvm/ops.c
View file @
76015021
...
...
@@ -215,15 +215,16 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER
(
REPLY_RX_PHY_CMD
,
iwl_mvm_rx_rx_phy_cmd
,
false
),
RX_HANDLER
(
TX_CMD
,
iwl_mvm_rx_tx_cmd
,
false
),
RX_HANDLER
(
BA_NOTIF
,
iwl_mvm_rx_ba_notif
,
false
),
RX_HANDLER
(
TIME_EVENT_NOTIFICATION
,
iwl_mvm_rx_time_event_notif
,
false
),
RX_HANDLER
(
SCAN_REQUEST_CMD
,
iwl_mvm_rx_scan_response
,
false
),
RX_HANDLER
(
SCAN_COMPLETE_NOTIFICATION
,
iwl_mvm_rx_scan_complete
,
false
),
RX_HANDLER
(
BT_PROFILE_NOTIFICATION
,
iwl_mvm_rx_bt_coex_notif
,
true
),
RX_HANDLER
(
BEACON_NOTIFICATION
,
iwl_mvm_rx_beacon_notif
,
false
),
RX_HANDLER
(
STATISTICS_NOTIFICATION
,
iwl_mvm_rx_statistics
,
true
),
RX_HANDLER
(
TIME_EVENT_NOTIFICATION
,
iwl_mvm_rx_time_event_notif
,
false
),
RX_HANDLER
(
SCAN_REQUEST_CMD
,
iwl_mvm_rx_scan_response
,
false
),
RX_HANDLER
(
SCAN_COMPLETE_NOTIFICATION
,
iwl_mvm_rx_scan_complete
,
false
),
RX_HANDLER
(
RADIO_VERSION_NOTIFICATION
,
iwl_mvm_rx_radio_ver
,
false
),
RX_HANDLER
(
CARD_STATE_NOTIFICATION
,
iwl_mvm_rx_card_state_notif
,
false
),
...
...
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
View file @
76015021
...
...
@@ -204,7 +204,8 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
{
int
ret
;
WARN_ON
(
ctxt
->
ref
);
WARN_ON
(
!
test_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
)
&&
ctxt
->
ref
);
lockdep_assert_held
(
&
mvm
->
mutex
);
ctxt
->
channel
=
chandef
->
chan
;
...
...
drivers/net/wireless/iwlwifi/mvm/power.c
View file @
76015021
...
...
@@ -168,6 +168,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return
;
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_POWER_SAVE_ENA_MSK
);
if
(
!
vif
->
bss_conf
.
assoc
)
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
if
(
mvmvif
->
dbgfs_pm
.
mask
&
MVM_DEBUGFS_PM_DISABLE_POWER_OFF
&&
...
...
@@ -246,6 +248,17 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
if
(
vif
->
type
!=
NL80211_IFTYPE_STATION
||
vif
->
p2p
)
return
0
;
/*
* TODO: The following vif_count verification is temporary condition.
* Avoid power mode update if more than one interface is currently
* active. Remove this condition when FW will support power management
* on multiple MACs.
*/
IWL_DEBUG_POWER
(
mvm
,
"Currently %d interfaces active
\n
"
,
mvm
->
vif_count
);
if
(
mvm
->
vif_count
>
1
)
return
0
;
iwl_mvm_power_build_cmd
(
mvm
,
vif
,
&
cmd
);
iwl_mvm_power_log
(
mvm
,
&
cmd
);
...
...
drivers/net/wireless/iwlwifi/mvm/quota.c
View file @
76015021
...
...
@@ -169,27 +169,34 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
num_active_bindings
++
;
}
if
(
!
num_active_bindings
)
goto
send_cmd
;
quota
=
IWL_MVM_MAX_QUOTA
/
num_active_bindings
;
quota_rem
=
IWL_MVM_MAX_QUOTA
%
num_active_bindings
;
quota
=
0
;
quota_rem
=
0
;
if
(
num_active_bindings
)
{
quota
=
IWL_MVM_MAX_QUOTA
/
num_active_bindings
;
quota_rem
=
IWL_MVM_MAX_QUOTA
%
num_active_bindings
;
}
for
(
idx
=
0
,
i
=
0
;
i
<
MAX_BINDINGS
;
i
++
)
{
if
(
data
.
n_interfaces
[
i
]
<=
0
)
if
(
data
.
colors
[
i
]
<
0
)
continue
;
cmd
.
quotas
[
idx
].
id_and_color
=
cpu_to_le32
(
FW_CMD_ID_AND_COLOR
(
i
,
data
.
colors
[
i
]));
cmd
.
quotas
[
idx
].
quota
=
cpu_to_le32
(
quota
);
cmd
.
quotas
[
idx
].
max_duration
=
cpu_to_le32
(
IWL_MVM_MAX_QUOTA
);
if
(
data
.
n_interfaces
[
i
]
<=
0
)
{
cmd
.
quotas
[
idx
].
quota
=
cpu_to_le32
(
0
);
cmd
.
quotas
[
idx
].
max_duration
=
cpu_to_le32
(
0
);
}
else
{
cmd
.
quotas
[
idx
].
quota
=
cpu_to_le32
(
quota
);
cmd
.
quotas
[
idx
].
max_duration
=
cpu_to_le32
(
IWL_MVM_MAX_QUOTA
);
}
idx
++
;
}
/* Give the remainder of the session to the first binding */
le32_add_cpu
(
&
cmd
.
quotas
[
0
].
quota
,
quota_rem
);
send_cmd:
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
TIME_QUOTA_CMD
,
CMD_SYNC
,
sizeof
(
cmd
),
&
cmd
);
if
(
ret
)
...
...
drivers/net/wireless/iwlwifi/mvm/rs.c
View file @
76015021
...
...
@@ -401,6 +401,17 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
load
=
rs_tl_get_load
(
lq_data
,
tid
);
/*
* Don't create TX aggregation sessions when in high
* BT traffic, as they would just be disrupted by BT.
*/
if
(
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
)
>=
2
)
{
IWL_DEBUG_COEX
(
mvm
,
"BT traffic (%d), no aggregation allowed
\n
"
,
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
));
return
ret
;
}
if
((
iwlwifi_mod_params
.
auto_agg
)
||
(
load
>
IWL_AGG_LOAD_THRESHOLD
))
{
IWL_DEBUG_HT
(
mvm
,
"Starting Tx agg: STA: %pM tid: %d
\n
"
,
sta
->
addr
,
tid
);
...
...
@@ -1519,6 +1530,29 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
u8
update_search_tbl_counter
=
0
;
int
ret
;
switch
(
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
))
{
case
IWL_BT_COEX_TRAFFIC_LOAD_NONE
:
/* nothing */
break
;
case
IWL_BT_COEX_TRAFFIC_LOAD_LOW
:
/* avoid antenna B unless MIMO */
if
(
tbl
->
action
==
IWL_SISO_SWITCH_ANTENNA2
)
tbl
->
action
=
IWL_SISO_SWITCH_MIMO2_AB
;
break
;
case
IWL_BT_COEX_TRAFFIC_LOAD_HIGH
:
case
IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS
:
/* avoid antenna B and MIMO */
valid_tx_ant
=
first_antenna
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
));
if
(
tbl
->
action
!=
IWL_SISO_SWITCH_ANTENNA1
)
tbl
->
action
=
IWL_SISO_SWITCH_ANTENNA1
;
break
;
default:
IWL_ERR
(
mvm
,
"Invalid BT load %d"
,
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
));
break
;
}
start_action
=
tbl
->
action
;
while
(
1
)
{
lq_sta
->
action_counter
++
;
...
...
@@ -1532,7 +1566,9 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
tx_chains_num
<=
2
))
break
;
if
(
window
->
success_ratio
>=
IWL_RS_GOOD_RATIO
)
if
(
window
->
success_ratio
>=
IWL_RS_GOOD_RATIO
&&
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
)
==
0
)
break
;
memcpy
(
search_tbl
,
tbl
,
sz
);
...
...
@@ -1654,6 +1690,28 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
u8
update_search_tbl_counter
=
0
;
int
ret
;
switch
(
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
))
{
case
IWL_BT_COEX_TRAFFIC_LOAD_NONE
:
/* nothing */
break
;
case
IWL_BT_COEX_TRAFFIC_LOAD_HIGH
:
case
IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS
:
/* avoid antenna B and MIMO */
if
(
tbl
->
action
!=
IWL_MIMO2_SWITCH_SISO_A
)
tbl
->
action
=
IWL_MIMO2_SWITCH_SISO_A
;
break
;
case
IWL_BT_COEX_TRAFFIC_LOAD_LOW
:
/* avoid antenna B unless MIMO */
if
(
tbl
->
action
==
IWL_MIMO2_SWITCH_SISO_B
||
tbl
->
action
==
IWL_MIMO2_SWITCH_SISO_C
)
tbl
->
action
=
IWL_MIMO2_SWITCH_SISO_A
;
break
;
default:
IWL_ERR
(
mvm
,
"Invalid BT load %d"
,
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
));
break
;
}
start_action
=
tbl
->
action
;
while
(
1
)
{
lq_sta
->
action_counter
++
;
...
...
@@ -1791,6 +1849,28 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
int
ret
;
u8
update_search_tbl_counter
=
0
;
switch
(
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
))
{
case
IWL_BT_COEX_TRAFFIC_LOAD_NONE
:
/* nothing */
break
;
case
IWL_BT_COEX_TRAFFIC_LOAD_HIGH
:
case
IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS
:
/* avoid antenna B and MIMO */
if
(
tbl
->
action
!=
IWL_MIMO3_SWITCH_SISO_A
)
tbl
->
action
=
IWL_MIMO3_SWITCH_SISO_A
;
break
;
case
IWL_BT_COEX_TRAFFIC_LOAD_LOW
:
/* avoid antenna B unless MIMO */
if
(
tbl
->
action
==
IWL_MIMO3_SWITCH_SISO_B
||
tbl
->
action
==
IWL_MIMO3_SWITCH_SISO_C
)
tbl
->
action
=
IWL_MIMO3_SWITCH_SISO_A
;
break
;
default:
IWL_ERR
(
mvm
,
"Invalid BT load %d"
,
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
));
break
;
}
start_action
=
tbl
->
action
;
while
(
1
)
{
lq_sta
->
action_counter
++
;
...
...
@@ -2302,6 +2382,32 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
(
current_tpt
>
(
100
*
tbl
->
expected_tpt
[
low
]))))
scale_action
=
0
;
if
((
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
)
>=
IWL_BT_COEX_TRAFFIC_LOAD_HIGH
)
&&
(
is_mimo2
(
tbl
->
lq_type
)
||
is_mimo3
(
tbl
->
lq_type
)))
{
if
(
lq_sta
->
last_bt_traffic
>
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
))
{
/*
* don't set scale_action, don't want to scale up if
* the rate scale doesn't otherwise think that is a
* good idea.
*/
}
else
if
(
lq_sta
->
last_bt_traffic
<=
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
))
{
scale_action
=
-
1
;
}
}
lq_sta
->
last_bt_traffic
=
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
);
if
((
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
)
>=
IWL_BT_COEX_TRAFFIC_LOAD_HIGH
)
&&
(
is_mimo2
(
tbl
->
lq_type
)
||
is_mimo3
(
tbl
->
lq_type
)))
{
/* search for a new modulation */
rs_stay_in_table
(
lq_sta
,
true
);
goto
lq_update
;
}
switch
(
scale_action
)
{
case
-
1
:
/* Decrease starting rate, update uCode's rate table */
...
...
@@ -2782,6 +2888,13 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
lq_cmd
->
agg_time_limit
=
cpu_to_le16
(
LINK_QUAL_AGG_TIME_LIMIT_DEF
);
/*
* overwrite if needed, pass aggregation time limit
* to uCode in uSec - This is racy - but heh, at least it helps...
*/
if
(
mvm
&&
BT_MBOX_MSG
(
&
mvm
->
last_bt_notif
,
3
,
TRAFFIC_LOAD
)
>=
2
)
lq_cmd
->
agg_time_limit
=
cpu_to_le16
(
1200
);
}
static
void
*
rs_alloc
(
struct
ieee80211_hw
*
hw
,
struct
dentry
*
debugfsdir
)
...
...
drivers/net/wireless/iwlwifi/mvm/rs.h
View file @
76015021
...
...
@@ -358,6 +358,18 @@ struct iwl_lq_sta {
u8
last_bt_traffic
;
};
enum
iwl_bt_coex_profile_traffic_load
{
IWL_BT_COEX_TRAFFIC_LOAD_NONE
=
0
,
IWL_BT_COEX_TRAFFIC_LOAD_LOW
=
1
,
IWL_BT_COEX_TRAFFIC_LOAD_HIGH
=
2
,
IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS
=
3
,
/*
* There are no more even though below is a u8, the
* indication from the BT device only has two bits.
*/
};
static
inline
u8
num_of_ant
(
u8
mask
)
{
return
!!
((
mask
)
&
ANT_A
)
+
...
...
drivers/net/wireless/iwlwifi/mvm/tt.c
View file @
76015021
...
...
@@ -371,6 +371,9 @@ static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac,
else
smps_mode
=
IEEE80211_SMPS_AUTOMATIC
;
if
(
vif
->
type
!=
NL80211_IFTYPE_STATION
)
return
;
iwl_mvm_update_smps
(
mvm
,
vif
,
IWL_MVM_SMPS_REQ_TT
,
smps_mode
);
}
...
...
drivers/net/wireless/iwlwifi/mvm/tx.c
View file @
76015021
...
...
@@ -175,7 +175,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
* table is controlled by LINK_QUALITY commands
*/
if
(
ieee80211_is_data
(
fc
))
{
if
(
ieee80211_is_data
(
fc
)
&&
sta
)
{
tx_cmd
->
initial_rate_index
=
0
;
tx_cmd
->
tx_flags
|=
cpu_to_le32
(
TX_CMD_FLG_STA_RATE
);
return
;
...
...
drivers/net/wireless/iwlwifi/mvm/utils.c
View file @
76015021
...
...
@@ -76,6 +76,11 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
{
int
ret
;
#if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
if
(
WARN_ON
(
mvm
->
d3_test_active
))
return
-
EIO
;
#endif
/*
* Synchronous commands from this op-mode must hold
* the mutex, this ensures we don't try to send two
...
...
@@ -125,6 +130,11 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
lockdep_assert_held
(
&
mvm
->
mutex
);
#if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
if
(
WARN_ON
(
mvm
->
d3_test_active
))
return
-
EIO
;
#endif
/*
* Only synchronous commands can wait for status,
* we use WANT_SKB so the caller can't.
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
View file @
76015021
...
...
@@ -578,9 +578,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
clear_bit
(
STATUS_RFKILL
,
&
trans_pcie
->
status
);
}
static
void
iwl_trans_pcie_d3_suspend
(
struct
iwl_trans
*
trans
)
static
void
iwl_trans_pcie_d3_suspend
(
struct
iwl_trans
*
trans
,
bool
test
)
{
iwl_disable_interrupts
(
trans
);
/*
* in testing mode, the host stays awake and the
* hardware won't be reset (not even partially)
*/
if
(
test
)
return
;
iwl_pcie_disable_ict
(
trans
);
iwl_clear_bit
(
trans
,
CSR_GP_CNTRL
,
...
...
@@ -599,11 +607,18 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans)
}
static
int
iwl_trans_pcie_d3_resume
(
struct
iwl_trans
*
trans
,
enum
iwl_d3_status
*
status
)
enum
iwl_d3_status
*
status
,
bool
test
)
{
u32
val
;
int
ret
;
if
(
test
)
{
iwl_enable_interrupts
(
trans
);
*
status
=
IWL_D3_STATUS_ALIVE
;
return
0
;
}
iwl_pcie_set_pwr
(
trans
,
false
);
val
=
iwl_read32
(
trans
,
CSR_RESET
);
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
View file @
76015021
...
...
@@ -1527,7 +1527,8 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
goto
cancel
;
}
if
(
test_bit
(
STATUS_RFKILL
,
&
trans_pcie
->
status
))
{
if
(
!
(
cmd
->
flags
&
CMD_SEND_IN_RFKILL
)
&&
test_bit
(
STATUS_RFKILL
,
&
trans_pcie
->
status
))
{
IWL_DEBUG_RF_KILL
(
trans
,
"RFKILL in SYNC CMD... no rsp
\n
"
);
ret
=
-
ERFKILL
;
goto
cancel
;
...
...
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