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
d72c7282
Commit
d72c7282
authored
Apr 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
655d8e23
2d055afd
Changes
22
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
678 additions
and
219 deletions
+678
-219
drivers/net/wireless/iwlwifi/dvm/agn.h
drivers/net/wireless/iwlwifi/dvm/agn.h
+5
-1
drivers/net/wireless/iwlwifi/dvm/lib.c
drivers/net/wireless/iwlwifi/dvm/lib.c
+13
-3
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
+5
-2
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/iwlwifi/dvm/tx.c
+45
-0
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-drv.c
+10
-4
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-trans.h
+1
-2
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+287
-46
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/d3.c
+8
-1
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
+119
-0
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+22
-42
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
+26
-7
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+25
-6
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+23
-4
drivers/net/wireless/iwlwifi/mvm/power.c
drivers/net/wireless/iwlwifi/mvm/power.c
+48
-67
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rs.c
+18
-18
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.c
+4
-4
drivers/net/wireless/iwlwifi/mvm/sta.h
drivers/net/wireless/iwlwifi/mvm/sta.h
+2
-0
drivers/net/wireless/iwlwifi/mvm/time-event.c
drivers/net/wireless/iwlwifi/mvm/time-event.c
+6
-4
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+8
-6
drivers/net/wireless/iwlwifi/mvm/utils.c
drivers/net/wireless/iwlwifi/mvm/utils.c
+1
-1
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/drv.c
+1
-0
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+1
-1
No files found.
drivers/net/wireless/iwlwifi/dvm/agn.h
View file @
d72c7282
...
...
@@ -73,6 +73,8 @@
/* AUX (TX during scan dwell) queue */
#define IWL_AUX_QUEUE 10
#define IWL_INVALID_STATION 255
/* device operations */
extern
struct
iwl_lib_ops
iwl1000_lib
;
extern
struct
iwl_lib_ops
iwl2000_lib
;
...
...
@@ -176,7 +178,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
/* lib */
int
iwlagn_send_tx_power
(
struct
iwl_priv
*
priv
);
void
iwlagn_temperature
(
struct
iwl_priv
*
priv
);
int
iwlagn_txfifo_flush
(
struct
iwl_priv
*
priv
);
int
iwlagn_txfifo_flush
(
struct
iwl_priv
*
priv
,
u32
scd_q_msk
);
void
iwlagn_dev_txfifo_flush
(
struct
iwl_priv
*
priv
);
int
iwlagn_send_beacon_cmd
(
struct
iwl_priv
*
priv
);
int
iwl_send_statistics_request
(
struct
iwl_priv
*
priv
,
...
...
@@ -210,6 +212,8 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct
ieee80211_sta
*
sta
,
u16
tid
,
u8
buf_size
);
int
iwlagn_tx_agg_stop
(
struct
iwl_priv
*
priv
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
u16
tid
);
int
iwlagn_tx_agg_flush
(
struct
iwl_priv
*
priv
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
u16
tid
);
int
iwlagn_rx_reply_compressed_ba
(
struct
iwl_priv
*
priv
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
...
...
drivers/net/wireless/iwlwifi/dvm/lib.c
View file @
d72c7282
...
...
@@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
* 1. acquire mutex before calling
* 2. make sure rf is on and not in exit state
*/
int
iwlagn_txfifo_flush
(
struct
iwl_priv
*
priv
)
int
iwlagn_txfifo_flush
(
struct
iwl_priv
*
priv
,
u32
scd_q_msk
)
{
struct
iwl_txfifo_flush_cmd
flush_cmd
;
struct
iwl_host_cmd
cmd
=
{
...
...
@@ -162,6 +162,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv)
if
(
priv
->
nvm_data
->
sku_cap_11n_enable
)
flush_cmd
.
queue_control
|=
IWL_AGG_TX_QUEUE_MSK
;
if
(
scd_q_msk
)
flush_cmd
.
queue_control
=
cpu_to_le32
(
scd_q_msk
);
IWL_DEBUG_INFO
(
priv
,
"queue control: 0x%x
\n
"
,
flush_cmd
.
queue_control
);
flush_cmd
.
flush_control
=
cpu_to_le16
(
IWL_DROP_ALL
);
...
...
@@ -173,7 +176,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
{
mutex_lock
(
&
priv
->
mutex
);
ieee80211_stop_queues
(
priv
->
hw
);
if
(
iwlagn_txfifo_flush
(
priv
))
{
if
(
iwlagn_txfifo_flush
(
priv
,
0
))
{
IWL_ERR
(
priv
,
"flush request fail
\n
"
);
goto
done
;
}
...
...
@@ -1084,7 +1087,14 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
struct
iwl_rxon_context
*
ctx
=
&
priv
->
contexts
[
IWL_RXON_CTX_BSS
];
struct
iwlagn_wowlan_kek_kck_material_cmd
kek_kck_cmd
;
struct
iwlagn_wowlan_tkip_params_cmd
tkip_cmd
=
{};
struct
iwlagn_d3_config_cmd
d3_cfg_cmd
=
{};
struct
iwlagn_d3_config_cmd
d3_cfg_cmd
=
{
/*
* Program the minimum sleep time to 10 seconds, as many
* platforms have issues processing a wakeup signal while
* still being in the process of suspending.
*/
.
min_sleep_time
=
cpu_to_le32
(
10
*
1000
*
1000
),
};
struct
wowlan_key_data
key_data
=
{
.
ctx
=
ctx
,
.
bssid
=
ctx
->
active
.
bssid_addr
,
...
...
drivers/net/wireless/iwlwifi/dvm/mac80211.c
View file @
d72c7282
...
...
@@ -777,9 +777,12 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
IWL_DEBUG_HT
(
priv
,
"start Tx
\n
"
);
ret
=
iwlagn_tx_agg_start
(
priv
,
vif
,
sta
,
tid
,
ssn
);
break
;
case
IEEE80211_AMPDU_TX_STOP_CONT
:
case
IEEE80211_AMPDU_TX_STOP_FLUSH
:
case
IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
:
IWL_DEBUG_HT
(
priv
,
"Flush Tx
\n
"
);
ret
=
iwlagn_tx_agg_flush
(
priv
,
vif
,
sta
,
tid
);
break
;
case
IEEE80211_AMPDU_TX_STOP_CONT
:
IWL_DEBUG_HT
(
priv
,
"stop Tx
\n
"
);
ret
=
iwlagn_tx_agg_stop
(
priv
,
vif
,
sta
,
tid
);
if
((
ret
==
0
)
&&
(
priv
->
agg_tids_count
>
0
))
{
...
...
@@ -1122,7 +1125,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
*/
if
(
drop
)
{
IWL_DEBUG_MAC80211
(
priv
,
"send flush command
\n
"
);
if
(
iwlagn_txfifo_flush
(
priv
))
{
if
(
iwlagn_txfifo_flush
(
priv
,
0
))
{
IWL_ERR
(
priv
,
"flush request fail
\n
"
);
goto
done
;
}
...
...
drivers/net/wireless/iwlwifi/dvm/tx.c
View file @
d72c7282
...
...
@@ -674,6 +674,51 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
return
ret
;
}
int
iwlagn_tx_agg_flush
(
struct
iwl_priv
*
priv
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
u16
tid
)
{
struct
iwl_tid_data
*
tid_data
;
enum
iwl_agg_state
agg_state
;
int
sta_id
,
txq_id
;
sta_id
=
iwl_sta_id
(
sta
);
/*
* First set the agg state to OFF to avoid calling
* ieee80211_stop_tx_ba_cb in iwlagn_check_ratid_empty.
*/
spin_lock_bh
(
&
priv
->
sta_lock
);
tid_data
=
&
priv
->
tid_data
[
sta_id
][
tid
];
txq_id
=
tid_data
->
agg
.
txq_id
;
agg_state
=
tid_data
->
agg
.
state
;
IWL_DEBUG_TX_QUEUES
(
priv
,
"Flush AGG: sta %d tid %d q %d state %d
\n
"
,
sta_id
,
tid
,
txq_id
,
tid_data
->
agg
.
state
);
tid_data
->
agg
.
state
=
IWL_AGG_OFF
;
spin_unlock_bh
(
&
priv
->
sta_lock
);
if
(
iwlagn_txfifo_flush
(
priv
,
BIT
(
txq_id
)))
IWL_ERR
(
priv
,
"Couldn't flush the AGG queue
\n
"
);
if
(
test_bit
(
txq_id
,
priv
->
agg_q_alloc
))
{
/*
* If the transport didn't know that we wanted to start
* agreggation, don't tell it that we want to stop them.
* This can happen when we don't get the addBA response on
* time, or we hadn't time to drain the AC queues.
*/
if
(
agg_state
==
IWL_AGG_ON
)
iwl_trans_txq_disable
(
priv
->
trans
,
txq_id
);
else
IWL_DEBUG_TX_QUEUES
(
priv
,
"Don't disable tx agg: %d
\n
"
,
agg_state
);
iwlagn_dealloc_agg_txq
(
priv
,
txq_id
);
}
return
0
;
}
int
iwlagn_tx_agg_oper
(
struct
iwl_priv
*
priv
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
u16
tid
,
u8
buf_size
)
{
...
...
drivers/net/wireless/iwlwifi/iwl-drv.c
View file @
d72c7282
...
...
@@ -912,8 +912,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
}
}
IWL_INFO
(
drv
,
"loaded firmware version %s"
,
drv
->
fw
.
fw_version
);
/*
* In mvm uCode there is no difference between data and instructions
* sections.
...
...
@@ -970,6 +968,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
else
op
=
&
iwlwifi_opmode_table
[
DVM_OP_MODE
];
IWL_INFO
(
drv
,
"loaded firmware version %s op_mode %s
\n
"
,
drv
->
fw
.
fw_version
,
op
->
name
);
/* add this device to the list of devices using this op_mode */
list_add_tail
(
&
drv
->
list
,
&
op
->
drv
);
...
...
@@ -997,8 +998,13 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
* else from proceeding if the module fails to load
* or hangs loading.
*/
if
(
load_module
)
request_module
(
"%s"
,
op
->
name
);
if
(
load_module
)
{
err
=
request_module
(
"%s"
,
op
->
name
);
if
(
err
)
IWL_ERR
(
drv
,
"failed to load module %s (error %d), is dynamic loading enabled?
\n
"
,
op
->
name
,
err
);
}
return
;
try_again:
...
...
drivers/net/wireless/iwlwifi/iwl-trans.h
View file @
d72c7282
...
...
@@ -305,7 +305,6 @@ static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r)
* currently supports
*/
#define IWL_MAX_HW_QUEUES 32
#define IWL_INVALID_STATION 255
#define IWL_MAX_TID_COUNT 8
#define IWL_FRAME_LIMIT 64
...
...
@@ -682,7 +681,7 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
static
inline
void
iwl_trans_ac_txq_enable
(
struct
iwl_trans
*
trans
,
int
queue
,
int
fifo
)
{
iwl_trans_txq_enable
(
trans
,
queue
,
fifo
,
IWL_INVALID_STATION
,
iwl_trans_txq_enable
(
trans
,
queue
,
fifo
,
-
1
,
IWL_MAX_TID_COUNT
,
IWL_FRAME_LIMIT
,
0
);
}
...
...
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
View file @
d72c7282
This diff is collapsed.
Click to expand it.
drivers/net/wireless/iwlwifi/mvm/d3.c
View file @
d72c7282
...
...
@@ -769,7 +769,14 @@ 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
=
{
/*
* Program the minimum sleep time to 10 seconds, as many
* platforms have issues processing a wakeup signal while
* still being in the process of suspending.
*/
.
min_sleep_time
=
cpu_to_le32
(
10
*
1000
*
1000
),
};
struct
wowlan_key_data
key_data
=
{
.
use_rsc_tsc
=
false
,
.
tkip
=
&
tkip_cmd
,
...
...
drivers/net/wireless/iwlwifi/mvm/debugfs.c
View file @
d72c7282
...
...
@@ -300,6 +300,67 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
return
count
;
}
static
ssize_t
iwl_dbgfs_mac_params_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
ieee80211_vif
*
vif
=
file
->
private_data
;
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
struct
iwl_mvm
*
mvm
=
mvmvif
->
dbgfs_data
;
u8
ap_sta_id
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
char
buf
[
512
];
int
bufsz
=
sizeof
(
buf
);
int
pos
=
0
;
int
i
;
mutex_lock
(
&
mvm
->
mutex
);
ap_sta_id
=
mvmvif
->
ap_sta_id
;
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"mac id/color: %d / %d
\n
"
,
mvmvif
->
id
,
mvmvif
->
color
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bssid: %pM
\n
"
,
vif
->
bss_conf
.
bssid
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"QoS:
\n
"
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
mvmvif
->
queue_params
);
i
++
)
{
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"
\t
%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d
\n
"
,
i
,
mvmvif
->
queue_params
[
i
].
txop
,
mvmvif
->
queue_params
[
i
].
cw_min
,
mvmvif
->
queue_params
[
i
].
cw_max
,
mvmvif
->
queue_params
[
i
].
aifs
,
mvmvif
->
queue_params
[
i
].
uapsd
);
}
if
(
vif
->
type
==
NL80211_IFTYPE_STATION
&&
ap_sta_id
!=
IWL_MVM_STATION_COUNT
)
{
struct
ieee80211_sta
*
sta
;
struct
iwl_mvm_sta
*
mvm_sta
;
sta
=
rcu_dereference_protected
(
mvm
->
fw_id_to_mac_id
[
ap_sta_id
],
lockdep_is_held
(
&
mvm
->
mutex
));
mvm_sta
=
(
void
*
)
sta
->
drv_priv
;
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"ap_sta_id %d - reduced Tx power %d
\n
"
,
ap_sta_id
,
mvm_sta
->
bt_reduced_txpower
);
}
rcu_read_lock
();
chanctx_conf
=
rcu_dereference
(
vif
->
chanctx_conf
);
if
(
chanctx_conf
)
{
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"idle rx chains %d, active rx chains: %d
\n
"
,
chanctx_conf
->
rx_chains_static
,
chanctx_conf
->
rx_chains_dynamic
);
}
rcu_read_unlock
();
mutex_unlock
(
&
mvm
->
mutex
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
}
#define BT_MBOX_MSG(_notif, _num, _field) \
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS)
...
...
@@ -464,6 +525,9 @@ MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
MVM_DEBUGFS_WRITE_FILE_OPS
(
power_down_d3_allow
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_restart
);
/* Interface specific debugfs entries */
MVM_DEBUGFS_READ_FILE_OPS
(
mac_params
);
int
iwl_mvm_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
dentry
*
dbgfs_dir
)
{
char
buf
[
100
];
...
...
@@ -494,3 +558,58 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
IWL_ERR
(
mvm
,
"Can't create the mvm debugfs directory
\n
"
);
return
-
ENOMEM
;
}
void
iwl_mvm_vif_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
struct
dentry
*
dbgfs_dir
=
vif
->
debugfs_dir
;
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
char
buf
[
100
];
if
(
!
dbgfs_dir
)
return
;
mvmvif
->
dbgfs_dir
=
debugfs_create_dir
(
"iwlmvm"
,
dbgfs_dir
);
mvmvif
->
dbgfs_data
=
mvm
;
if
(
!
mvmvif
->
dbgfs_dir
)
{
IWL_ERR
(
mvm
,
"Failed to create debugfs directory under %s
\n
"
,
dbgfs_dir
->
d_name
.
name
);
return
;
}
MVM_DEBUGFS_ADD_FILE_VIF
(
mac_params
,
mvmvif
->
dbgfs_dir
,
S_IRUSR
);
/*
* Create symlink for convenience pointing to interface specific
* debugfs entries for the driver. For example, under
* /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
* find
* netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
*/
snprintf
(
buf
,
100
,
"../../../%s/%s/%s/%s"
,
dbgfs_dir
->
d_parent
->
d_parent
->
d_name
.
name
,
dbgfs_dir
->
d_parent
->
d_name
.
name
,
dbgfs_dir
->
d_name
.
name
,
mvmvif
->
dbgfs_dir
->
d_name
.
name
);
mvmvif
->
dbgfs_slink
=
debugfs_create_symlink
(
dbgfs_dir
->
d_name
.
name
,
mvm
->
debugfs_dir
,
buf
);
if
(
!
mvmvif
->
dbgfs_slink
)
IWL_ERR
(
mvm
,
"Can't create debugfs symbolic link under %s
\n
"
,
dbgfs_dir
->
d_name
.
name
);
return
;
err:
IWL_ERR
(
mvm
,
"Can't create debugfs entity
\n
"
);
}
void
iwl_mvm_vif_dbgfs_clean
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
debugfs_remove
(
mvmvif
->
dbgfs_slink
);
mvmvif
->
dbgfs_slink
=
NULL
;
debugfs_remove_recursive
(
mvmvif
->
dbgfs_dir
);
mvmvif
->
dbgfs_dir
=
NULL
;
}
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
View file @
d72c7282
...
...
@@ -68,73 +68,53 @@
/**
* enum iwl_scan_flags - masks for power table command flags
* @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
* receiver and transmitter. '0' - does not allow.
* @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
* '1' Driver enables PM (use rest of parameters)
* @POWER_FLAGS_S
LEE
P_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
* @POWER_FLAGS_S
KI
P_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
* '1' PM could sleep over DTIM till listen Interval.
* @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
* @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all
* access categories are both delivery and trigger enabled.
* @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and
* PBW Snoozing enabled
* @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
* @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
*/
enum
iwl_power_flags
{
POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
=
BIT
(
0
),
POWER_FLAGS_SLEEP_OVER_DTIM_MSK
=
BIT
(
1
),
POWER_FLAGS_LPRX_ENA_MSK
=
BIT
(
2
),
POWER_FLAGS_SNOOZE_ENA_MSK
=
BIT
(
3
),
POWER_FLAGS_BT_SCO_ENA
=
BIT
(
4
),
POWER_FLAGS_ADVANCE_PM_ENA_MSK
=
BIT
(
5
)
POWER_FLAGS_POWER_SAVE_ENA_MSK
=
BIT
(
0
),
POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
=
BIT
(
1
),
POWER_FLAGS_SKIP_OVER_DTIM_MSK
=
BIT
(
2
),
POWER_FLAGS_ADVANCE_PM_ENA_MSK
=
BIT
(
9
),
POWER_FLAGS_LPRX_ENA_MSK
=
BIT
(
11
),
};
#define IWL_POWER_VEC_SIZE 5
/**
* struct iwl_powertable_cmd - Power Table Command
* POWER_TABLE_CMD = 0x77 (command, has simple generic response)
*
* @id_and_color: MAC contex identifier
* @action: Action on context - no action, add new,
* modify existent, remove
* @flags: Power table command flags from POWER_FLAGS_*
* @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec.
* Minimum allowed:- 3 * DTIM
* Minimum allowed:- 3 * DTIM. Keep alive period must be
* set regardless of power scheme or current power state.
* FW use this value also when PM is disabled.
* @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to
* PSM transition - legacy PM
* @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
* PSM transition - legacy PM
* @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to
* PSM transition - uAPSD
* @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to
* PSM transition - uAPSD
* @sleep_interval: not in use
* @keep_alive_beacons: not in use
* @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
* Default: 80dbm
* @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set
* @snooze_interval: TBD
* @snooze_window: TBD
* @snooze_step: TBD
* @qndp_tid: TBD
* @uapsd_ac_flags: TBD
* @uapsd_max_sp: TBD
*/
struct
iwl_powertable_cmd
{
/* COMMON_INDEX_HDR_API_S_VER_1 */
__le32
id_and_color
;
__le32
action
;
/* PM_POWER_TABLE_CMD_API_S_VER_5 */
__le16
flags
;
u8
reserved
;
__le16
keep_alive_second
s
;
u8
keep_alive_seconds
;
u8
debug_flag
s
;
__le32
rx_data_timeout
;
__le32
tx_data_timeout
;
__le32
rx_data_timeout_uapsd
;
__le32
tx_data_timeout_uapsd
;
u8
lprx_rssi_threshold
;
u8
num_skip_dtim
;
__le16
snooze_interval
;
__le16
snooze_window
;
u8
snooze_step
;
u8
qndp_tid
;
u8
uapsd_ac_flags
;
u8
uapsd_max_sp
;
__le32
sleep_interval
[
IWL_POWER_VEC_SIZE
];
__le32
keep_alive_beacons
;
__le32
lprx_rssi_threshold
;
}
__packed
;
#endif
drivers/net/wireless/iwlwifi/mvm/fw-api.h
View file @
d72c7282
...
...
@@ -480,15 +480,34 @@ enum {
TE_DEP_TSF
=
2
,
TE_EVENT_SOCIOPATHIC
=
4
,
};
/* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */
/* When to send Time Event notifications and to whom (internal = FW) */
/*
* Supported Time event notifications configuration.
* A notification (both event and fragment) includes a status indicating weather
* the FW was able to schedule the event or not. For fragment start/end
* notification the status is always success. There is no start/end fragment
* notification for monolithic events.
*
* @TE_NOTIF_NONE: no notifications
* @TE_NOTIF_HOST_EVENT_START: request/receive notification on event start
* @TE_NOTIF_HOST_EVENT_END:request/receive notification on event end
* @TE_NOTIF_INTERNAL_EVENT_START: internal FW use
* @TE_NOTIF_INTERNAL_EVENT_END: internal FW use.
* @TE_NOTIF_HOST_FRAG_START: request/receive notification on frag start
* @TE_NOTIF_HOST_FRAG_END:request/receive notification on frag end
* @TE_NOTIF_INTERNAL_FRAG_START: internal FW use.
* @TE_NOTIF_INTERNAL_FRAG_END: internal FW use.
*/
enum
{
TE_NOTIF_NONE
=
0
,
TE_NOTIF_HOST_START
=
0x1
,
TE_NOTIF_HOST_END
=
0x2
,
TE_NOTIF_INTERNAL_START
=
0x4
,
TE_NOTIF_INTERNAL_END
=
0x8
};
/* MAC_EVENT_ACTION_API_E_VER_1 */
TE_NOTIF_HOST_EVENT_START
=
0x1
,
TE_NOTIF_HOST_EVENT_END
=
0x2
,
TE_NOTIF_INTERNAL_EVENT_START
=
0x4
,
TE_NOTIF_INTERNAL_EVENT_END
=
0x8
,
TE_NOTIF_HOST_FRAG_START
=
0x10
,
TE_NOTIF_HOST_FRAG_END
=
0x20
,
TE_NOTIF_INTERNAL_FRAG_START
=
0x40
,
TE_NOTIF_INTERNAL_FRAG_END
=
0x80
};
/* MAC_EVENT_ACTION_API_E_VER_2 */
/*
* @TE_FRAG_NONE: fragmentation of the time event is NOT allowed.
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
View file @
d72c7282
...
...
@@ -502,11 +502,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
/*
* TODO: remove this temporary code.
* Currently MVM FW supports power management only on single MAC.
* Iterate and disable PM on all active interfaces.
* If new interface added, disable PM on existing interface.
* P2P device is a special case, since it is handled by FW similary to
* scan. If P2P deviced is added, PM remains enabled on existing
* interface.
* Note: the method below does not count the new interface being added
* at this moment.
*/
mvm
->
vif_count
++
;
if
(
vif
->
type
!=
NL80211_IFTYPE_P2P_DEVICE
)
mvm
->
vif_count
++
;
if
(
mvm
->
vif_count
>
1
)
{
IWL_DEBUG_MAC80211
(
mvm
,
"Disable power on existing interfaces
\n
"
);
...
...
@@ -562,6 +566,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
mvm
->
p2p_device_vif
=
vif
;
}
iwl_mvm_vif_dbgfs_register
(
mvm
,
vif
);
goto
out_unlock
;
out_unbind:
...
...
@@ -575,10 +580,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
/*
* TODO: remove this temporary code.
* Currently MVM FW supports power management only on single MAC.
* Check if only one additional interface remains after re
r
easing
* Check if only one additional interface remains after re
l
easing
* current one. Update power mode on the remaining interface.
*/
mvm
->
vif_count
--
;
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
)
{
...
...
@@ -640,6 +646,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
mutex_lock
(
&
mvm
->
mutex
);
iwl_mvm_vif_dbgfs_clean
(
mvm
,
vif
);
/*
* For AP/GO interface, the tear down of the resources allocated to the
* interface is be handled as part of the stop_ap flow.
...
...
@@ -663,7 +671,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
* Check if only one additional interface remains after removing
* current one. Update power mode on the remaining interface.
*/
if
(
mvm
->
vif_count
)
if
(
mvm
->
vif_count
&&
vif
->
type
!=
NL80211_IFTYPE_P2P_DEVICE
)
mvm
->
vif_count
--
;
IWL_DEBUG_MAC80211
(
mvm
,
"Currently %d interfaces active
\n
"
,
mvm
->
vif_count
);
...
...
@@ -713,6 +721,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
IWL_ERR
(
mvm
,
"failed to update quotas
\n
"
);
return
;
}
iwl_mvm_bt_coex_vif_assoc
(
mvm
,
vif
);
}
else
if
(
mvmvif
->
ap_sta_id
!=
IWL_MVM_STATION_COUNT
)
{
/* remove AP station now that the MAC is unassoc */
ret
=
iwl_mvm_rm_sta_id
(
mvm
,
vif
,
mvmvif
->
ap_sta_id
);
...
...
@@ -931,7 +940,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
*/
break
;
case
STA_NOTIFY_AWAKE
:
if
(
WARN_ON
(
mvmsta
->
sta_id
==
IWL_
INVALID_STATION
))
if
(
WARN_ON
(
mvmsta
->
sta_id
==
IWL_
MVM_STATION_COUNT
))
break
;
iwl_mvm_sta_modify_ps_wake
(
mvm
,
sta
);
break
;
...
...
@@ -1326,6 +1335,15 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
return
iwl_mvm_mac_ctxt_beacon_changed
(
mvm
,
mvm_sta
->
vif
);
}
static
void
iwl_mvm_mac_rssi_callback
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
iwl_mvm_bt_rssi_event
(
mvm
,
vif
,
rssi_event
);
}
struct
ieee80211_ops
iwl_mvm_hw_ops
=
{
.
tx
=
iwl_mvm_mac_tx
,
.
ampdu_action
=
iwl_mvm_mac_ampdu_action
,
...
...
@@ -1349,6 +1367,7 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
.
update_tkip_key
=
iwl_mvm_mac_update_tkip_key
,
.
remain_on_channel
=
iwl_mvm_roc
,
.
cancel_remain_on_channel
=
iwl_mvm_cancel_roc
,
.
rssi_callback
=
iwl_mvm_mac_rssi_callback
,
.
add_chanctx
=
iwl_mvm_add_chanctx
,
.
remove_chanctx
=
iwl_mvm_remove_chanctx
,
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
View file @
d72c7282
...
...
@@ -212,6 +212,7 @@ struct iwl_mvm_vif {
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct
dentry
*
dbgfs_dir
;
struct
dentry
*
dbgfs_slink
;
void
*
dbgfs_data
;
#endif
};
...
...
@@ -321,6 +322,13 @@ struct iwl_mvm {
* can hold 16 keys at most. Reflect this fact.
*/
unsigned
long
fw_key_table
[
BITS_TO_LONGS
(
STA_KEY_MAX_NUM
)];
/*
* This counter of created interfaces is referenced only in conjunction
* with FW limitation related to power management. Currently PM is
* supported only on a single interface.
* IMPORTANT: this variable counts all interfaces except P2P device.
*/
u8
vif_count
;
struct
led_classdev
led
;
...
...
@@ -471,16 +479,22 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
/* MVM debugfs */
#ifdef CONFIG_IWLWIFI_DEBUGFS
int
iwl_mvm_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
dentry
*
dbgfs_dir
);
int
iwl_mvm_vif_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
dentry
*
dbgfs_dir
);
void
iwl_power_get_params
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_powertable_cmd
*
cmd
);
void
iwl_mvm_vif_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
void
iwl_mvm_vif_dbgfs_clean
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
#else
static
inline
int
iwl_mvm_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
dentry
*
dbgfs_dir
)
{
return
0
;
}
static
inline
void
iwl_mvm_vif_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
}
static
inline
void
iwl_mvm_vif_dbgfs_clean
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
}
#endif
/* CONFIG_IWLWIFI_DEBUGFS */
/* rate scaling */
...
...
@@ -490,6 +504,8 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
/* power managment */
int
iwl_mvm_power_update_mode
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
int
iwl_mvm_power_disable
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
void
iwl_mvm_power_build_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_powertable_cmd
*
cmd
);
int
iwl_mvm_leds_init
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_leds_exit
(
struct
iwl_mvm
*
mvm
);
...
...
@@ -513,5 +529,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
int
iwl_mvm_rx_bt_coex_notif
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
void
iwl_mvm_bt_rssi_event
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
);
void
iwl_mvm_bt_coex_vif_assoc
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
#endif
/* __IWL_MVM_H__ */
drivers/net/wireless/iwlwifi/mvm/power.c
View file @
d72c7282
...
...
@@ -75,23 +75,49 @@
#define POWER_KEEP_ALIVE_PERIOD_SEC 25
static
void
iwl_power_build_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_powertable_cmd
*
cmd
)
static
void
iwl_mvm_power_log
(
struct
iwl_mvm
*
mvm
,
struct
iwl_powertable_cmd
*
cmd
)
{
IWL_DEBUG_POWER
(
mvm
,
"Sending power table command for power level %d, flags = 0x%X
\n
"
,
iwlmvm_mod_params
.
power_scheme
,
le16_to_cpu
(
cmd
->
flags
));
IWL_DEBUG_POWER
(
mvm
,
"Keep alive = %u sec
\n
"
,
cmd
->
keep_alive_seconds
);
if
(
cmd
->
flags
&
cpu_to_le16
(
POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
))
{
IWL_DEBUG_POWER
(
mvm
,
"Rx timeout = %u usec
\n
"
,
le32_to_cpu
(
cmd
->
rx_data_timeout
));
IWL_DEBUG_POWER
(
mvm
,
"Tx timeout = %u usec
\n
"
,
le32_to_cpu
(
cmd
->
tx_data_timeout
));
IWL_DEBUG_POWER
(
mvm
,
"LP RX RSSI threshold = %u
\n
"
,
cmd
->
lprx_rssi_threshold
);
}
}
void
iwl_mvm_power_build_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_powertable_cmd
*
cmd
)
{
struct
ieee80211_hw
*
hw
=
mvm
->
hw
;
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_channel
*
chan
;
int
dtimper
,
dtimper_msec
;
int
keep_alive
;
bool
radar_detect
=
false
;
cmd
->
id_and_color
=
cpu_to_le32
(
FW_CMD_ID_AND_COLOR
(
mvmvif
->
id
,
mvmvif
->
color
));
cmd
->
action
=
cpu_to_le32
(
FW_CTXT_ACTION_MODIFY
);
/*
* Regardless of power management state the driver must set
* keep alive period. FW will use it for sending keep alive NDPs
* immediately after association.
*/
cmd
->
keep_alive_seconds
=
POWER_KEEP_ALIVE_PERIOD_SEC
;
if
((
iwlmvm_mod_params
.
power_scheme
==
IWL_POWER_SCHEME_CAM
)
||
!
iwlwifi_mod_params
.
power_save
)
return
;
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_POWER_SAVE_ENA_MSK
);
if
((
!
vif
->
bss_conf
.
ps
)
||
(
iwlmvm_mod_params
.
power_scheme
==
IWL_POWER_SCHEME_CAM
))
if
(
!
vif
->
bss_conf
.
ps
)
return
;
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
);
...
...
@@ -110,26 +136,23 @@ static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
/* Check skip over DTIM conditions */
if
(
!
radar_detect
&&
(
dtimper
<=
10
)
&&
(
iwlmvm_mod_params
.
power_scheme
==
IWL_POWER_SCHEME_LP
))
{
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_SLEEP_OVER_DTIM_MSK
);
cmd
->
num_skip_dtim
=
2
;
}
(
iwlmvm_mod_params
.
power_scheme
==
IWL_POWER_SCHEME_LP
))
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_SKIP_OVER_DTIM_MSK
);
/* Check that keep alive period is at least 3 * DTIM */
dtimper_msec
=
dtimper
*
vif
->
bss_conf
.
beacon_int
;
keep_alive
=
max_t
(
int
,
3
*
dtimper_msec
,
MSEC_PER_SEC
*
POWER_KEEP_ALIVE_PERIOD_SEC
);
MSEC_PER_SEC
*
cmd
->
keep_alive_seconds
);
keep_alive
=
DIV_ROUND_UP
(
keep_alive
,
MSEC_PER_SEC
);
cmd
->
keep_alive_seconds
=
cpu_to_le16
(
keep_alive
);
cmd
->
keep_alive_seconds
=
keep_alive
;
if
(
iwlmvm_mod_params
.
power_scheme
==
IWL_POWER_SCHEME_LP
)
{
/* TODO: Also for D3 (device sleep / WoWLAN) */
cmd
->
rx_data_timeout
=
cpu_to_le32
(
10
);
cmd
->
tx_data_timeout
=
cpu_to_le32
(
10
);
cmd
->
rx_data_timeout
=
cpu_to_le32
(
10
*
USEC_PER_MSEC
);
cmd
->
tx_data_timeout
=
cpu_to_le32
(
10
*
USEC_PER_MSEC
);
}
else
{
cmd
->
rx_data_timeout
=
cpu_to_le32
(
50
);
cmd
->
tx_data_timeout
=
cpu_to_le32
(
50
);
cmd
->
rx_data_timeout
=
cpu_to_le32
(
100
*
USEC_PER_MSEC
);
cmd
->
tx_data_timeout
=
cpu_to_le32
(
100
*
USEC_PER_MSEC
);
}
}
...
...
@@ -137,36 +160,11 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
struct
iwl_powertable_cmd
cmd
=
{};
if
(
!
iwlwifi_mod_params
.
power_save
)
{
IWL_DEBUG_POWER
(
mvm
,
"Power management is not allowed
\n
"
);
return
0
;
}
if
(
vif
->
type
!=
NL80211_IFTYPE_STATION
||
vif
->
p2p
)
return
0
;
iwl_power_build_cmd
(
mvm
,
vif
,
&
cmd
);
IWL_DEBUG_POWER
(
mvm
,
"Sending power table command on mac id 0x%X for power level %d, flags = 0x%X
\n
"
,
cmd
.
id_and_color
,
iwlmvm_mod_params
.
power_scheme
,
le16_to_cpu
(
cmd
.
flags
));
if
(
cmd
.
flags
&
cpu_to_le16
(
POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
))
{
IWL_DEBUG_POWER
(
mvm
,
"Keep alive = %u sec
\n
"
,
le16_to_cpu
(
cmd
.
keep_alive_seconds
));
IWL_DEBUG_POWER
(
mvm
,
"Rx timeout = %u usec
\n
"
,
le32_to_cpu
(
cmd
.
rx_data_timeout
));
IWL_DEBUG_POWER
(
mvm
,
"Tx timeout = %u usec
\n
"
,
le32_to_cpu
(
cmd
.
tx_data_timeout
));
IWL_DEBUG_POWER
(
mvm
,
"Rx timeout (uAPSD) = %u usec
\n
"
,
le32_to_cpu
(
cmd
.
rx_data_timeout_uapsd
));
IWL_DEBUG_POWER
(
mvm
,
"Tx timeout = %u usec
\n
"
,
le32_to_cpu
(
cmd
.
tx_data_timeout_uapsd
));
IWL_DEBUG_POWER
(
mvm
,
"LP RX RSSI threshold = %u
\n
"
,
cmd
.
lprx_rssi_threshold
);
IWL_DEBUG_POWER
(
mvm
,
"DTIMs to skip = %u
\n
"
,
cmd
.
num_skip_dtim
);
}
iwl_mvm_power_build_cmd
(
mvm
,
vif
,
&
cmd
);
iwl_mvm_power_log
(
mvm
,
&
cmd
);
return
iwl_mvm_send_cmd_pdu
(
mvm
,
POWER_TABLE_CMD
,
CMD_SYNC
,
sizeof
(
cmd
),
&
cmd
);
...
...
@@ -175,33 +173,16 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
int
iwl_mvm_power_disable
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_powertable_cmd
cmd
=
{};
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
if
(
!
iwlwifi_mod_params
.
power_save
)
{
IWL_DEBUG_POWER
(
mvm
,
"Power management is not allowed
\n
"
);
return
0
;
}
if
(
vif
->
type
!=
NL80211_IFTYPE_STATION
||
vif
->
p2p
)
return
0
;
cmd
.
id_and_color
=
cpu_to_le32
(
FW_CMD_ID_AND_COLOR
(
mvmvif
->
id
,
mvmvif
->
color
));
cmd
.
action
=
cpu_to_le32
(
FW_CTXT_ACTION_MODIFY
);
if
((
iwlmvm_mod_params
.
power_scheme
!=
IWL_POWER_SCHEME_CAM
)
&&
iwlwifi_mod_params
.
power_save
)
cmd
.
flags
|=
cpu_to_le16
(
POWER_FLAGS_POWER_SAVE_ENA_MSK
);
IWL_DEBUG_POWER
(
mvm
,
"Sending power table command on mac id 0x%X for power level %d, flags = 0x%X
\n
"
,
cmd
.
id_and_color
,
iwlmvm_mod_params
.
power_scheme
,
le16_to_cpu
(
cmd
.
flags
));
iwl_mvm_power_log
(
mvm
,
&
cmd
);
return
iwl_mvm_send_cmd_pdu
(
mvm
,
POWER_TABLE_CMD
,
CMD_ASYNC
,
sizeof
(
cmd
),
&
cmd
);
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
void
iwl_power_get_params
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_powertable_cmd
*
cmd
)
{
iwl_power_build_cmd
(
mvm
,
vif
,
cmd
);
}
#endif
/* CONFIG_IWLWIFI_DEBUGFS */
drivers/net/wireless/iwlwifi/mvm/rs.c
View file @
d72c7282
...
...
@@ -793,7 +793,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
if
(
num_of_ant
(
tbl
->
ant_type
)
>
1
)
tbl
->
ant_type
=
first_antenna
(
mvm
->
nvm_data
->
valid_tx_ant
);
first_antenna
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
);
tbl
->
is_ht40
=
0
;
tbl
->
is_SGI
=
0
;
...
...
@@ -1235,7 +1235,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
return
-
1
;
/* Need both Tx chains/antennas to support MIMO */
if
(
num_of_ant
(
mvm
->
nvm_data
->
valid_tx_ant
)
<
2
)
if
(
num_of_ant
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
)
<
2
)
return
-
1
;
IWL_DEBUG_RATE
(
mvm
,
"LQ: try to switch to MIMO2
\n
"
);
...
...
@@ -1287,7 +1287,7 @@ static int rs_switch_to_mimo3(struct iwl_mvm *mvm,
return
-
1
;
/* Need both Tx chains/antennas to support MIMO */
if
(
num_of_ant
(
mvm
->
nvm_data
->
valid_tx_ant
)
<
3
)
if
(
num_of_ant
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
)
<
3
)
return
-
1
;
IWL_DEBUG_RATE
(
mvm
,
"LQ: try to switch to MIMO3
\n
"
);
...
...
@@ -1381,7 +1381,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
u32
sz
=
(
sizeof
(
struct
iwl_scale_tbl_info
)
-
(
sizeof
(
struct
iwl_rate_scale_data
)
*
IWL_RATE_COUNT
));
u8
start_action
;
u8
valid_tx_ant
=
mvm
->
nvm_data
->
valid_tx_ant
;
u8
valid_tx_ant
=
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
u8
tx_chains_num
=
num_of_ant
(
valid_tx_ant
);
int
ret
;
u8
update_search_tbl_counter
=
0
;
...
...
@@ -1514,7 +1514,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
u32
sz
=
(
sizeof
(
struct
iwl_scale_tbl_info
)
-
(
sizeof
(
struct
iwl_rate_scale_data
)
*
IWL_RATE_COUNT
));
u8
start_action
;
u8
valid_tx_ant
=
mvm
->
nvm_data
->
valid_tx_ant
;
u8
valid_tx_ant
=
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
u8
tx_chains_num
=
num_of_ant
(
valid_tx_ant
);
u8
update_search_tbl_counter
=
0
;
int
ret
;
...
...
@@ -1649,7 +1649,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
u32
sz
=
(
sizeof
(
struct
iwl_scale_tbl_info
)
-
(
sizeof
(
struct
iwl_rate_scale_data
)
*
IWL_RATE_COUNT
));
u8
start_action
;
u8
valid_tx_ant
=
mvm
->
nvm_data
->
valid_tx_ant
;
u8
valid_tx_ant
=
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
u8
tx_chains_num
=
num_of_ant
(
valid_tx_ant
);
u8
update_search_tbl_counter
=
0
;
int
ret
;
...
...
@@ -1786,7 +1786,7 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
u32
sz
=
(
sizeof
(
struct
iwl_scale_tbl_info
)
-
(
sizeof
(
struct
iwl_rate_scale_data
)
*
IWL_RATE_COUNT
));
u8
start_action
;
u8
valid_tx_ant
=
mvm
->
nvm_data
->
valid_tx_ant
;
u8
valid_tx_ant
=
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
u8
tx_chains_num
=
num_of_ant
(
valid_tx_ant
);
int
ret
;
u8
update_search_tbl_counter
=
0
;
...
...
@@ -2449,7 +2449,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
i
=
lq_sta
->
last_txrate_idx
;
valid_tx_ant
=
mvm
->
nvm_data
->
valid_tx_ant
;
valid_tx_ant
=
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
if
(
!
lq_sta
->
search_better_tbl
)
active_tbl
=
lq_sta
->
active_tbl
;
...
...
@@ -2639,15 +2639,15 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
/* These values will be overridden later */
lq_sta
->
lq
.
single_stream_ant_msk
=
first_antenna
(
mvm
->
nvm_data
->
valid_tx_ant
);
first_antenna
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
);
lq_sta
->
lq
.
dual_stream_ant_msk
=
mvm
->
nvm_data
->
valid_tx_ant
&
~
first_antenna
(
mvm
->
nvm_data
->
valid_tx_ant
);
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
&
~
first_antenna
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
);
if
(
!
lq_sta
->
lq
.
dual_stream_ant_msk
)
{
lq_sta
->
lq
.
dual_stream_ant_msk
=
ANT_AB
;
}
else
if
(
num_of_ant
(
mvm
->
nvm_data
->
valid_tx_ant
)
==
2
)
{
}
else
if
(
num_of_ant
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
)
==
2
)
{
lq_sta
->
lq
.
dual_stream_ant_msk
=
mvm
->
nvm_data
->
valid_tx_ant
;
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
}
/* as default allow aggregation for all tids */
...
...
@@ -2708,7 +2708,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
index
++
;
repeat_rate
--
;
if
(
mvm
)
valid_tx_ant
=
mvm
->
nvm_data
->
valid_tx_ant
;
valid_tx_ant
=
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
/* Fill rest of rate table */
while
(
index
<
LINK_QUAL_MAX_RETRY_NUM
)
{
...
...
@@ -2813,7 +2813,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u8
ant_sel_tx
;
mvm
=
lq_sta
->
drv
;
valid_tx_ant
=
mvm
->
nvm_data
->
valid_tx_ant
;
valid_tx_ant
=
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
;
if
(
lq_sta
->
dbg_fixed_rate
)
{
ant_sel_tx
=
((
lq_sta
->
dbg_fixed_rate
&
RATE_MCS_ANT_ABC_MSK
)
...
...
@@ -2884,9 +2884,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
desc
+=
sprintf
(
buff
+
desc
,
"fixed rate 0x%X
\n
"
,
lq_sta
->
dbg_fixed_rate
);
desc
+=
sprintf
(
buff
+
desc
,
"valid_tx_ant %s%s%s
\n
"
,
(
mvm
->
nvm_data
->
valid_tx_ant
&
ANT_A
)
?
"ANT_A,"
:
""
,
(
mvm
->
nvm_data
->
valid_tx_ant
&
ANT_B
)
?
"ANT_B,"
:
""
,
(
mvm
->
nvm_data
->
valid_tx_ant
&
ANT_C
)
?
"ANT_C"
:
""
);
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
&
ANT_A
)
?
"ANT_A,"
:
""
,
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
&
ANT_B
)
?
"ANT_B,"
:
""
,
(
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
&
ANT_C
)
?
"ANT_C"
:
""
);
desc
+=
sprintf
(
buff
+
desc
,
"lq type %s
\n
"
,
(
is_legacy
(
tbl
->
lq_type
))
?
"legacy"
:
"HT"
);
if
(
is_Ht
(
tbl
->
lq_type
))
{
...
...
drivers/net/wireless/iwlwifi/mvm/sta.c
View file @
d72c7282
...
...
@@ -945,7 +945,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
mvmvif
->
ap_sta_id
!=
IWL_MVM_STATION_COUNT
)
return
mvmvif
->
ap_sta_id
;
return
IWL_
INVALID_STATION
;
return
IWL_
MVM_STATION_COUNT
;
}
static
int
iwl_mvm_send_sta_key
(
struct
iwl_mvm
*
mvm
,
...
...
@@ -1093,7 +1093,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
/* Get the station id from the mvm local station table */
sta_id
=
iwl_mvm_get_key_sta_id
(
vif
,
sta
);
if
(
sta_id
==
IWL_
INVALID_STATION
)
{
if
(
sta_id
==
IWL_
MVM_STATION_COUNT
)
{
IWL_ERR
(
mvm
,
"Failed to find station id
\n
"
);
return
-
EINVAL
;
}
...
...
@@ -1188,7 +1188,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
return
-
ENOENT
;
}
if
(
sta_id
==
IWL_
INVALID_STATION
)
{
if
(
sta_id
==
IWL_
MVM_STATION_COUNT
)
{
IWL_DEBUG_WEP
(
mvm
,
"station non-existent, early return.
\n
"
);
return
0
;
}
...
...
@@ -1254,7 +1254,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
struct
iwl_mvm_sta
*
mvm_sta
;
u8
sta_id
=
iwl_mvm_get_key_sta_id
(
vif
,
sta
);
if
(
WARN_ON_ONCE
(
sta_id
==
IWL_
INVALID_STATION
))
if
(
WARN_ON_ONCE
(
sta_id
==
IWL_
MVM_STATION_COUNT
))
return
;
rcu_read_lock
();
...
...
drivers/net/wireless/iwlwifi/mvm/sta.h
View file @
d72c7282
...
...
@@ -271,6 +271,7 @@ struct iwl_mvm_tid_data {
* @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for
* tid.
* @max_agg_bufsize: the maximal size of the AGG buffer for this station
* @bt_reduced_txpower: is reduced tx power enabled for this station
* @lock: lock to protect the whole struct. Since %tid_data is access from Tx
* and from Tx response flow, it needs a spinlock.
* @pending_frames: number of frames for this STA on the shared Tx queues.
...
...
@@ -287,6 +288,7 @@ struct iwl_mvm_sta {
u32
mac_id_n_color
;
u16
tid_disable_agg
;
u8
max_agg_bufsize
;
bool
bt_reduced_txpower
;
spinlock_t
lock
;
atomic_t
pending_frames
;
struct
iwl_mvm_tid_data
tid_data
[
IWL_MAX_TID_COUNT
];
...
...
drivers/net/wireless/iwlwifi/mvm/time-event.c
View file @
d72c7282
...
...
@@ -166,7 +166,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
WARN_ONCE
(
!
le32_to_cpu
(
notif
->
status
),
"Failed to schedule time event
\n
"
);
if
(
le32_to_cpu
(
notif
->
action
)
==
TE_NOTIF_HOS
T_END
)
{
if
(
le32_to_cpu
(
notif
->
action
)
&
TE_NOTIF_HOST_EVEN
T_END
)
{
IWL_DEBUG_TE
(
mvm
,
"TE ended - current time %lu, estimated end %lu
\n
"
,
jiffies
,
te_data
->
end_jiffies
);
...
...
@@ -189,7 +189,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
}
iwl_mvm_te_clear_data
(
mvm
,
te_data
);
}
else
if
(
le32_to_cpu
(
notif
->
action
)
==
TE_NOTIF_HOS
T_START
)
{
}
else
if
(
le32_to_cpu
(
notif
->
action
)
&
TE_NOTIF_HOST_EVEN
T_START
)
{
te_data
->
running
=
true
;
te_data
->
end_jiffies
=
jiffies
+
TU_TO_JIFFIES
(
te_data
->
duration
);
...
...
@@ -368,7 +368,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
time_cmd
.
interval_reciprocal
=
cpu_to_le32
(
iwl_mvm_reciprocal
(
1
));
time_cmd
.
duration
=
cpu_to_le32
(
duration
);
time_cmd
.
repeat
=
cpu_to_le32
(
1
);
time_cmd
.
notify
=
cpu_to_le32
(
TE_NOTIF_HOST_START
|
TE_NOTIF_HOST_END
);
time_cmd
.
notify
=
cpu_to_le32
(
TE_NOTIF_HOST_EVENT_START
|
TE_NOTIF_HOST_EVENT_END
);
iwl_mvm_time_event_send_add
(
mvm
,
vif
,
te_data
,
&
time_cmd
);
}
...
...
@@ -485,7 +486,8 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
time_cmd
.
max_delay
=
cpu_to_le32
(
MSEC_TO_TU
(
duration
/
2
));
time_cmd
.
duration
=
cpu_to_le32
(
MSEC_TO_TU
(
duration
));
time_cmd
.
repeat
=
cpu_to_le32
(
1
);
time_cmd
.
notify
=
cpu_to_le32
(
TE_NOTIF_HOST_START
|
TE_NOTIF_HOST_END
);
time_cmd
.
notify
=
cpu_to_le32
(
TE_NOTIF_HOST_EVENT_START
|
TE_NOTIF_HOST_EVENT_END
);
return
iwl_mvm_time_event_send_add
(
mvm
,
vif
,
te_data
,
&
time_cmd
);
}
...
...
drivers/net/wireless/iwlwifi/mvm/tx.c
View file @
d72c7282
...
...
@@ -205,7 +205,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
rate_plcp
=
iwl_mvm_mac80211_idx_to_hwrate
(
rate_idx
);
mvm
->
mgmt_last_antenna_idx
=
iwl_mvm_next_antenna
(
mvm
,
mvm
->
nvm_data
->
valid_tx_ant
,
iwl_mvm_next_antenna
(
mvm
,
iwl_fw_valid_tx_ant
(
mvm
->
fw
)
,
mvm
->
mgmt_last_antenna_idx
);
rate_flags
=
BIT
(
mvm
->
mgmt_last_antenna_idx
)
<<
RATE_MCS_ANT_POS
;
...
...
@@ -365,7 +365,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
if
(
WARN_ON_ONCE
(
!
mvmsta
))
return
-
1
;
if
(
WARN_ON_ONCE
(
mvmsta
->
sta_id
==
IWL_
INVALID_STATION
))
if
(
WARN_ON_ONCE
(
mvmsta
->
sta_id
==
IWL_
MVM_STATION_COUNT
))
return
-
1
;
dev_cmd
=
iwl_mvm_set_tx_params
(
mvm
,
skb
,
sta
,
mvmsta
->
sta_id
);
...
...
@@ -641,10 +641,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
}
IWL_DEBUG_TX_REPLY
(
mvm
,
"TXQ %d status %s (0x%08x)
\n\t\t\t\t
initial_rate 0x%x "
"retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x
\n
"
,
txq_id
,
iwl_mvm_get_tx_fail_reason
(
status
),
status
,
le32_to_cpu
(
tx_resp
->
initial_rate
),
"TXQ %d status %s (0x%08x)
\n
"
,
txq_id
,
iwl_mvm_get_tx_fail_reason
(
status
),
status
);
IWL_DEBUG_TX_REPLY
(
mvm
,
"
\t\t\t\t
initial_rate 0x%x retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x
\n
"
,
le32_to_cpu
(
tx_resp
->
initial_rate
),
tx_resp
->
failure_frame
,
SEQ_TO_INDEX
(
sequence
),
ssn
,
next_reclaimed
,
seq_ctl
);
...
...
drivers/net/wireless/iwlwifi/mvm/utils.c
View file @
d72c7282
...
...
@@ -462,7 +462,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
.
data
=
{
lq
,
},
};
if
(
WARN_ON
(
lq
->
sta_id
==
IWL_
INVALID_STATION
))
if
(
WARN_ON
(
lq
->
sta_id
==
IWL_
MVM_STATION_COUNT
))
return
-
EINVAL
;
if
(
WARN_ON
(
init
&&
(
cmd
.
flags
&
CMD_ASYNC
)))
...
...
drivers/net/wireless/iwlwifi/pcie/drv.c
View file @
d72c7282
...
...
@@ -241,6 +241,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{
IWL_PCI_DEVICE
(
0x088F
,
0x4260
,
iwl6035_2agn_cfg
)},
{
IWL_PCI_DEVICE
(
0x088E
,
0x4460
,
iwl6035_2agn_cfg
)},
{
IWL_PCI_DEVICE
(
0x088E
,
0x4860
,
iwl6035_2agn_cfg
)},
{
IWL_PCI_DEVICE
(
0x088F
,
0x5260
,
iwl6035_2agn_cfg
)},
/* 105 Series */
{
IWL_PCI_DEVICE
(
0x0894
,
0x0022
,
iwl105_bgn_cfg
)},
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
View file @
d72c7282
...
...
@@ -1063,7 +1063,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
iwl_set_bits_prph
(
trans
,
SCD_QUEUECHAIN_SEL
,
BIT
(
txq_id
));
/* If this queue is mapped to a certain station: it is an AGG queue */
if
(
sta_id
!=
IWL_INVALID_STATION
)
{
if
(
sta_id
>=
0
)
{
u16
ra_tid
=
BUILD_RAxTID
(
sta_id
,
tid
);
/* Map receiver-address / traffic-ID to this queue */
...
...
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