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
eb2eacf7
Commit
eb2eacf7
authored
Sep 15, 2014
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
167bf96d
f991e17b
Changes
41
Hide whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
634 additions
and
521 deletions
+634
-521
drivers/net/wireless/iwlwifi/dvm/power.c
drivers/net/wireless/iwlwifi/dvm/power.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-7000.c
+27
-4
drivers/net/wireless/iwlwifi/iwl-8000.c
drivers/net/wireless/iwlwifi/iwl-8000.c
+13
-1
drivers/net/wireless/iwlwifi/iwl-config.h
drivers/net/wireless/iwlwifi/iwl-config.h
+9
-0
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-csr.h
+10
-0
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-drv.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+3
-0
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/iwl-fw.h
+2
-0
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-io.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+4
-3
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-trans.h
+2
-6
drivers/net/wireless/iwlwifi/mvm/Makefile
drivers/net/wireless/iwlwifi/mvm/Makefile
+1
-1
drivers/net/wireless/iwlwifi/mvm/coex.c
drivers/net/wireless/iwlwifi/mvm/coex.c
+7
-6
drivers/net/wireless/iwlwifi/mvm/constants.h
drivers/net/wireless/iwlwifi/mvm/constants.h
+8
-0
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+1
-2
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
+15
-0
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
+37
-3
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/fw.c
+3
-0
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+10
-10
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+54
-121
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+22
-8
drivers/net/wireless/iwlwifi/mvm/nvm.c
drivers/net/wireless/iwlwifi/mvm/nvm.c
+2
-1
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/ops.c
+18
-0
drivers/net/wireless/iwlwifi/mvm/power.c
drivers/net/wireless/iwlwifi/mvm/power.c
+36
-31
drivers/net/wireless/iwlwifi/mvm/quota.c
drivers/net/wireless/iwlwifi/mvm/quota.c
+26
-6
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rs.c
+30
-38
drivers/net/wireless/iwlwifi/mvm/rs.h
drivers/net/wireless/iwlwifi/mvm/rs.h
+6
-4
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/rx.c
+3
-3
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/scan.c
+2
-2
drivers/net/wireless/iwlwifi/mvm/sf.c
drivers/net/wireless/iwlwifi/mvm/sf.c
+5
-1
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.c
+11
-1
drivers/net/wireless/iwlwifi/mvm/tdls.c
drivers/net/wireless/iwlwifi/mvm/tdls.c
+149
-0
drivers/net/wireless/iwlwifi/mvm/time-event.c
drivers/net/wireless/iwlwifi/mvm/time-event.c
+5
-5
drivers/net/wireless/iwlwifi/mvm/time-event.h
drivers/net/wireless/iwlwifi/mvm/time-event.h
+4
-4
drivers/net/wireless/iwlwifi/mvm/tt.c
drivers/net/wireless/iwlwifi/mvm/tt.c
+79
-247
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+7
-3
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/drv.c
+8
-0
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/internal.h
+2
-0
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/rx.c
+1
-1
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+2
-1
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+7
-5
No files found.
drivers/net/wireless/iwlwifi/dvm/power.c
View file @
eb2eacf7
...
...
@@ -40,7 +40,7 @@
#include "commands.h"
#include "power.h"
static
bool
force_cam
;
static
bool
force_cam
=
true
;
module_param
(
force_cam
,
bool
,
0644
);
MODULE_PARM_DESC
(
force_cam
,
"force continuously aware mode (no power saving at all)"
);
...
...
drivers/net/wireless/iwlwifi/iwl-7000.c
View file @
eb2eacf7
...
...
@@ -85,6 +85,8 @@
#define IWL7260_TX_POWER_VERSION 0xffff
/* meaningless */
#define IWL3160_NVM_VERSION 0x709
#define IWL3160_TX_POWER_VERSION 0xffff
/* meaningless */
#define IWL3165_NVM_VERSION 0x709
#define IWL3165_TX_POWER_VERSION 0xffff
/* meaningless */
#define IWL7265_NVM_VERSION 0x0a1d
#define IWL7265_TX_POWER_VERSION 0xffff
/* meaningless */
...
...
@@ -94,6 +96,9 @@
#define IWL3160_FW_PRE "iwlwifi-3160-"
#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode"
#define IWL3165_FW_PRE "iwlwifi-3165-"
#define IWL3165_MODULE_FIRMWARE(api) IWL3165_FW_PRE __stringify(api) ".ucode"
#define IWL7265_FW_PRE "iwlwifi-7265-"
#define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
...
...
@@ -126,7 +131,8 @@ static const struct iwl_ht_params iwl7000_ht_params = {
.max_data_size = IWL60_RTC_DATA_SIZE, \
.base_params = &iwl7000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
.non_shared_ant = ANT_A
const
struct
iwl_cfg
iwl7260_2ac_cfg
=
{
...
...
@@ -215,11 +221,27 @@ static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = {
{
0
},
};
static
const
struct
iwl_ht_params
iwl7265_ht_params
=
{
.
stbc
=
true
,
.
ldpc
=
true
,
.
ht40_bands
=
BIT
(
IEEE80211_BAND_2GHZ
)
|
BIT
(
IEEE80211_BAND_5GHZ
),
};
const
struct
iwl_cfg
iwl3165_2ac_cfg
=
{
.
name
=
"Intel(R) Dual Band Wireless AC 3165"
,
.
fw_name_pre
=
IWL3165_FW_PRE
,
IWL_DEVICE_7000
,
.
ht_params
=
&
iwl7000_ht_params
,
.
nvm_ver
=
IWL3165_NVM_VERSION
,
.
nvm_calib_ver
=
IWL3165_TX_POWER_VERSION
,
.
pwr_tx_backoffs
=
iwl7265_pwr_tx_backoffs
,
};
const
struct
iwl_cfg
iwl7265_2ac_cfg
=
{
.
name
=
"Intel(R) Dual Band Wireless AC 7265"
,
.
fw_name_pre
=
IWL7265_FW_PRE
,
IWL_DEVICE_7000
,
.
ht_params
=
&
iwl7
000
_ht_params
,
.
ht_params
=
&
iwl7
265
_ht_params
,
.
nvm_ver
=
IWL7265_NVM_VERSION
,
.
nvm_calib_ver
=
IWL7265_TX_POWER_VERSION
,
.
pwr_tx_backoffs
=
iwl7265_pwr_tx_backoffs
,
...
...
@@ -229,7 +251,7 @@ const struct iwl_cfg iwl7265_2n_cfg = {
.
name
=
"Intel(R) Dual Band Wireless N 7265"
,
.
fw_name_pre
=
IWL7265_FW_PRE
,
IWL_DEVICE_7000
,
.
ht_params
=
&
iwl7
000
_ht_params
,
.
ht_params
=
&
iwl7
265
_ht_params
,
.
nvm_ver
=
IWL7265_NVM_VERSION
,
.
nvm_calib_ver
=
IWL7265_TX_POWER_VERSION
,
.
pwr_tx_backoffs
=
iwl7265_pwr_tx_backoffs
,
...
...
@@ -239,7 +261,7 @@ const struct iwl_cfg iwl7265_n_cfg = {
.
name
=
"Intel(R) Wireless N 7265"
,
.
fw_name_pre
=
IWL7265_FW_PRE
,
IWL_DEVICE_7000
,
.
ht_params
=
&
iwl7
000
_ht_params
,
.
ht_params
=
&
iwl7
265
_ht_params
,
.
nvm_ver
=
IWL7265_NVM_VERSION
,
.
nvm_calib_ver
=
IWL7265_TX_POWER_VERSION
,
.
pwr_tx_backoffs
=
iwl7265_pwr_tx_backoffs
,
...
...
@@ -247,4 +269,5 @@ const struct iwl_cfg iwl7265_n_cfg = {
MODULE_FIRMWARE
(
IWL7260_MODULE_FIRMWARE
(
IWL7260_UCODE_API_OK
));
MODULE_FIRMWARE
(
IWL3160_MODULE_FIRMWARE
(
IWL3160_UCODE_API_OK
));
MODULE_FIRMWARE
(
IWL3165_MODULE_FIRMWARE
(
IWL3160_UCODE_API_OK
));
MODULE_FIRMWARE
(
IWL7265_MODULE_FIRMWARE
(
IWL7260_UCODE_API_OK
));
drivers/net/wireless/iwlwifi/iwl-8000.c
View file @
eb2eacf7
...
...
@@ -103,6 +103,7 @@ static const struct iwl_base_params iwl8000_base_params = {
};
static
const
struct
iwl_ht_params
iwl8000_ht_params
=
{
.
ldpc
=
true
,
.
ht40_bands
=
BIT
(
IEEE80211_BAND_2GHZ
)
|
BIT
(
IEEE80211_BAND_5GHZ
),
};
...
...
@@ -115,7 +116,17 @@ static const struct iwl_ht_params iwl8000_ht_params = {
.max_data_size = IWL60_RTC_DATA_SIZE, \
.base_params = &iwl8000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
.non_shared_ant = ANT_A
const
struct
iwl_cfg
iwl8260_2n_cfg
=
{
.
name
=
"Intel(R) Dual Band Wireless N 8260"
,
.
fw_name_pre
=
IWL8000_FW_PRE
,
IWL_DEVICE_8000
,
.
ht_params
=
&
iwl8000_ht_params
,
.
nvm_ver
=
IWL8000_NVM_VERSION
,
.
nvm_calib_ver
=
IWL8000_TX_POWER_VERSION
,
};
const
struct
iwl_cfg
iwl8260_2ac_cfg
=
{
.
name
=
"Intel(R) Dual Band Wireless AC 8260"
,
...
...
@@ -135,6 +146,7 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
.
nvm_calib_ver
=
IWL8000_TX_POWER_VERSION
,
.
default_nvm_file
=
DEFAULT_NVM_FILE_FAMILY_8000
,
.
max_rx_agg_size
=
MAX_RX_AGG_SIZE_8260_SDIO
,
.
disable_dummy_notification
=
true
,
};
MODULE_FIRMWARE
(
IWL8000_MODULE_FIRMWARE
(
IWL8000_UCODE_API_OK
));
drivers/net/wireless/iwlwifi/iwl-config.h
View file @
eb2eacf7
...
...
@@ -120,6 +120,8 @@ enum iwl_led_mode {
#define IWL_LONG_WD_TIMEOUT 10000
#define IWL_MAX_WD_TIMEOUT 120000
#define IWL_DEFAULT_MAX_TX_POWER 22
/* Antenna presence definitions */
#define ANT_NONE 0x0
#define ANT_A BIT(0)
...
...
@@ -169,6 +171,7 @@ struct iwl_base_params {
/*
* @stbc: support Tx STBC and 1*SS Rx STBC
* @ldpc: support Tx/Rx with LDPC
* @use_rts_for_aggregation: use rts/cts protection for HT traffic
* @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40
*/
...
...
@@ -176,6 +179,7 @@ struct iwl_ht_params {
enum
ieee80211_smps_mode
smps_mode
;
const
bool
ht_greenfield_support
;
/* if used set to true */
const
bool
stbc
;
const
bool
ldpc
;
bool
use_rts_for_aggregation
;
u8
ht40_bands
;
};
...
...
@@ -226,6 +230,7 @@ struct iwl_pwr_tx_backoff {
* @max_data_size: The maximal length of the fw data section
* @valid_tx_ant: valid transmit antenna
* @valid_rx_ant: valid receive antenna
* @non_shared_ant: the antenna that is for WiFi only
* @nvm_ver: NVM version
* @nvm_calib_ver: NVM calibration version
* @lib: pointer to the lib ops
...
...
@@ -258,6 +263,7 @@ struct iwl_cfg {
const
u32
max_inst_size
;
u8
valid_tx_ant
;
u8
valid_rx_ant
;
u8
non_shared_ant
;
bool
bt_shared_single_ant
;
u16
nvm_ver
;
u16
nvm_calib_ver
;
...
...
@@ -278,6 +284,7 @@ struct iwl_cfg {
bool
no_power_up_nic_in_init
;
const
char
*
default_nvm_file
;
unsigned
int
max_rx_agg_size
;
bool
disable_dummy_notification
;
};
/*
...
...
@@ -335,9 +342,11 @@ extern const struct iwl_cfg iwl7260_n_cfg;
extern
const
struct
iwl_cfg
iwl3160_2ac_cfg
;
extern
const
struct
iwl_cfg
iwl3160_2n_cfg
;
extern
const
struct
iwl_cfg
iwl3160_n_cfg
;
extern
const
struct
iwl_cfg
iwl3165_2ac_cfg
;
extern
const
struct
iwl_cfg
iwl7265_2ac_cfg
;
extern
const
struct
iwl_cfg
iwl7265_2n_cfg
;
extern
const
struct
iwl_cfg
iwl7265_n_cfg
;
extern
const
struct
iwl_cfg
iwl8260_2n_cfg
;
extern
const
struct
iwl_cfg
iwl8260_2ac_cfg
;
extern
const
struct
iwl_cfg
iwl8260_2ac_sdio_cfg
;
#endif
/* CONFIG_IWLMVM */
...
...
drivers/net/wireless/iwlwifi/iwl-csr.h
View file @
eb2eacf7
...
...
@@ -295,6 +295,16 @@
#define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0)
#define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2)
/**
* hw_rev values
*/
enum
{
SILICON_A_STEP
=
0
,
SILICON_B_STEP
,
};
#define CSR_HW_REV_TYPE_MSK (0x000FFF0)
#define CSR_HW_REV_TYPE_5300 (0x0000020)
#define CSR_HW_REV_TYPE_5350 (0x0000030)
...
...
drivers/net/wireless/iwlwifi/iwl-drv.c
View file @
eb2eacf7
...
...
@@ -1363,7 +1363,7 @@ MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)")
module_param_named
(
antenna_coupling
,
iwlwifi_mod_params
.
ant_coupling
,
int
,
S_IRUGO
);
MODULE_PARM_DESC
(
antenna_coupling
,
"specify antenna coupling in dB (def
ua
lt: 0 dB)"
);
"specify antenna coupling in dB (def
au
lt: 0 dB)"
);
module_param_named
(
wd_disable
,
iwlwifi_mod_params
.
wd_disable
,
int
,
S_IRUGO
);
MODULE_PARM_DESC
(
wd_disable
,
...
...
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
View file @
eb2eacf7
...
...
@@ -758,6 +758,9 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
ht_info
->
cap
|=
IEEE80211_HT_CAP_TX_STBC
;
}
if
(
cfg
->
ht_params
->
ldpc
)
ht_info
->
cap
|=
IEEE80211_HT_CAP_LDPC_CODING
;
if
(
iwlwifi_mod_params
.
amsdu_size_8K
)
ht_info
->
cap
|=
IEEE80211_HT_CAP_MAX_AMSDU
;
...
...
drivers/net/wireless/iwlwifi/iwl-fw.h
View file @
eb2eacf7
...
...
@@ -127,6 +127,7 @@ enum iwl_ucode_tlv_flag {
* @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
* @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
* @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
* @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
* @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
* longer than the passive one, which is essential for fragmented scan.
*/
...
...
@@ -137,6 +138,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_CSA_FLOW
=
BIT
(
4
),
IWL_UCODE_TLV_API_DISABLE_STA_TX
=
BIT
(
5
),
IWL_UCODE_TLV_API_LMAC_SCAN
=
BIT
(
6
),
IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF
=
BIT
(
7
),
IWL_UCODE_TLV_API_FRAGMENTED_SCAN
=
BIT
(
8
),
};
...
...
drivers/net/wireless/iwlwifi/iwl-io.c
View file @
eb2eacf7
...
...
@@ -193,7 +193,7 @@ void iwl_force_nmi(struct iwl_trans *trans)
* DEVICE_SET_NMI_8000B_REG - is used.
*/
if
((
trans
->
cfg
->
device_family
!=
IWL_DEVICE_FAMILY_8000
)
||
(
(
trans
->
hw_rev
&
0xc
)
==
0x0
))
(
CSR_HW_REV_STEP
(
trans
->
hw_rev
)
==
SILICON_A_STEP
))
iwl_write_prph
(
trans
,
DEVICE_SET_NMI_REG
,
DEVICE_SET_NMI_VAL
);
else
iwl_write_prph
(
trans
,
DEVICE_SET_NMI_8000B_REG
,
...
...
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
View file @
eb2eacf7
...
...
@@ -148,8 +148,6 @@ static const u8 iwl_nvm_channels_family_8000[] = {
#define LAST_2GHZ_HT_PLUS 9
#define LAST_5GHZ_HT 161
#define DEFAULT_MAX_TX_POWER 16
/* rate data (static) */
static
struct
ieee80211_rate
iwl_cfg80211_rates
[]
=
{
{
.
bitrate
=
1
*
10
,
.
hw_value
=
0
,
.
hw_value_short
=
0
,
},
...
...
@@ -297,7 +295,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
* Default value - highest tx power value. max_power
* is not used in mvm, and is used for backwards compatibility
*/
channel
->
max_power
=
DEFAULT_MAX_TX_POWER
;
channel
->
max_power
=
IWL_
DEFAULT_MAX_TX_POWER
;
is_5ghz
=
channel
->
band
==
IEEE80211_BAND_5GHZ
;
IWL_DEBUG_EEPROM
(
dev
,
"Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported
\n
"
,
...
...
@@ -336,6 +334,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
3
<<
IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT
|
7
<<
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT
;
if
(
cfg
->
ht_params
->
ldpc
)
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_RXLDPC
;
if
(
num_tx_ants
>
1
)
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_TXSTBC
;
else
...
...
drivers/net/wireless/iwlwifi/iwl-trans.h
View file @
eb2eacf7
...
...
@@ -377,6 +377,7 @@ enum iwl_trans_status {
* if unset 4k will be the RX buffer size
* @bc_table_dword: set to true if the BC table expects the byte count to be
* in DWORD (as opposed to bytes)
* @scd_set_active: should the transport configure the SCD for HCMD queue
* @queue_watchdog_timeout: time (in ms) after which queues
* are considered stuck and will trigger device restart
* @command_names: array of command names, must be 256 entries
...
...
@@ -392,6 +393,7 @@ struct iwl_trans_config {
bool
rx_buf_size_8k
;
bool
bc_table_dword
;
bool
scd_set_active
;
unsigned
int
queue_watchdog_timeout
;
const
char
*
const
*
command_names
;
};
...
...
@@ -826,12 +828,6 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
iwl_trans_txq_enable_cfg
(
trans
,
queue
,
0
,
&
cfg
);
}
static
inline
void
iwl_trans_txq_enable_no_scd
(
struct
iwl_trans
*
trans
,
int
queue
,
u16
ssn
)
{
iwl_trans_txq_enable_cfg
(
trans
,
queue
,
ssn
,
NULL
);
}
static
inline
int
iwl_trans_wait_tx_queue_empty
(
struct
iwl_trans
*
trans
,
u32
txq_bm
)
{
...
...
drivers/net/wireless/iwlwifi/mvm/Makefile
View file @
eb2eacf7
...
...
@@ -3,7 +3,7 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
iwlmvm-y
+=
utils.o rx.o tx.o binding.o quota.o sta.o sf.o
iwlmvm-y
+=
scan.o time-event.o rs.o
iwlmvm-y
+=
power.o coex.o coex_legacy.o
iwlmvm-y
+=
tt.o offloading.o
iwlmvm-y
+=
tt.o offloading.o
tdls.o
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS)
+=
debugfs.o debugfs-vif.o
iwlmvm-$(CONFIG_IWLWIFI_LEDS)
+=
led.o
iwlmvm-$(CONFIG_PM_SLEEP)
+=
d3.o
...
...
drivers/net/wireless/iwlwifi/mvm/coex.c
View file @
eb2eacf7
...
...
@@ -587,8 +587,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
unlikely
(
mvm
->
bt_force_ant_mode
!=
BT_FORCE_ANT_DIS
))
{
u32
mode
;
switch
(
mvm
->
bt_force_ant_mode
)
{
case
BT_FORCE_ANT_BT
:
mode
=
BT_COEX_BT
;
...
...
@@ -758,7 +756,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
struct
iwl_bt_iterator_data
*
data
=
_data
;
struct
iwl_mvm
*
mvm
=
data
->
mvm
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
enum
ieee80211_smps_mode
smps_mode
;
/* default smps_mode is AUTOMATIC - only used for client modes */
enum
ieee80211_smps_mode
smps_mode
=
IEEE80211_SMPS_AUTOMATIC
;
u32
bt_activity_grading
;
int
ave_rssi
;
...
...
@@ -766,8 +765,6 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
switch
(
vif
->
type
)
{
case
NL80211_IFTYPE_STATION
:
/* default smps_mode for BSS / P2P client is AUTOMATIC */
smps_mode
=
IEEE80211_SMPS_AUTOMATIC
;
break
;
case
NL80211_IFTYPE_AP
:
if
(
!
mvmvif
->
ap_ibss_active
)
...
...
@@ -799,7 +796,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
else
if
(
bt_activity_grading
>=
BT_LOW_TRAFFIC
)
smps_mode
=
IEEE80211_SMPS_DYNAMIC
;
/* relax SMPS contraints for next association */
/* relax SMPS con
s
traints for next association */
if
(
!
vif
->
bss_conf
.
assoc
)
smps_mode
=
IEEE80211_SMPS_AUTOMATIC
;
...
...
@@ -1149,6 +1146,10 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
bool
iwl_mvm_bt_coex_is_shared_ant_avail
(
struct
iwl_mvm
*
mvm
)
{
/* there is no other antenna, shared antenna is always available */
if
(
mvm
->
cfg
->
bt_shared_single_ant
)
return
true
;
if
(
!
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_BT_COEX_SPLIT
))
return
iwl_mvm_bt_coex_is_shared_ant_avail_old
(
mvm
);
...
...
drivers/net/wireless/iwlwifi/mvm/constants.h
View file @
eb2eacf7
...
...
@@ -65,12 +65,18 @@
#ifndef __MVM_CONSTANTS_H
#define __MVM_CONSTANTS_H
#include <linux/ieee80211.h>
#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
#define IWL_MVM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20
#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8
#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30
...
...
@@ -86,5 +92,7 @@
#define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING 1
#define IWL_MVM_BT_COEX_MPLUT 1
#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
#define IWL_MVM_QUOTA_THRESHOLD 8
#endif
/* __MVM_CONSTANTS_H */
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
View file @
eb2eacf7
...
...
@@ -76,8 +76,7 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
switch
(
param
)
{
case
MVM_DEBUGFS_PM_KEEP_ALIVE
:
{
struct
ieee80211_hw
*
hw
=
mvm
->
hw
;
int
dtimper
=
hw
->
conf
.
ps_dtim_period
?:
1
;
int
dtimper
=
vif
->
bss_conf
.
dtim_period
?:
1
;
int
dtimper_msec
=
dtimper
*
vif
->
bss_conf
.
beacon_int
;
IWL_DEBUG_POWER
(
mvm
,
"debugfs: set keep_alive= %d sec
\n
"
,
val
);
...
...
drivers/net/wireless/iwlwifi/mvm/debugfs.c
View file @
eb2eacf7
...
...
@@ -288,6 +288,9 @@ static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
{
int
temperature
;
if
(
!
mvm
->
ucode_loaded
&&
!
mvm
->
temperature_test
)
return
-
EIO
;
if
(
kstrtoint
(
buf
,
10
,
&
temperature
))
return
-
EINVAL
;
/* not a legal temperature */
...
...
@@ -1256,6 +1259,18 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
PRINT_MVM_REF
(
IWL_MVM_REF_P2P_CLIENT
);
PRINT_MVM_REF
(
IWL_MVM_REF_AP_IBSS
);
PRINT_MVM_REF
(
IWL_MVM_REF_USER
);
PRINT_MVM_REF
(
IWL_MVM_REF_TX
);
PRINT_MVM_REF
(
IWL_MVM_REF_TX_AGG
);
PRINT_MVM_REF
(
IWL_MVM_REF_ADD_IF
);
PRINT_MVM_REF
(
IWL_MVM_REF_START_AP
);
PRINT_MVM_REF
(
IWL_MVM_REF_BSS_CHANGED
);
PRINT_MVM_REF
(
IWL_MVM_REF_PREPARE_TX
);
PRINT_MVM_REF
(
IWL_MVM_REF_PROTECT_TDLS
);
PRINT_MVM_REF
(
IWL_MVM_REF_CHECK_CTKILL
);
PRINT_MVM_REF
(
IWL_MVM_REF_PRPH_READ
);
PRINT_MVM_REF
(
IWL_MVM_REF_PRPH_WRITE
);
PRINT_MVM_REF
(
IWL_MVM_REF_NMI
);
PRINT_MVM_REF
(
IWL_MVM_REF_TM_CMD
);
PRINT_MVM_REF
(
IWL_MVM_REF_EXIT_WORK
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api.h
View file @
eb2eacf7
...
...
@@ -205,6 +205,10 @@ enum {
REPLY_SF_CFG_CMD
=
0xd1
,
REPLY_BEACON_FILTERING_CMD
=
0xd2
,
/* DTS measurements */
CMD_DTS_MEASUREMENT_TRIGGER
=
0xdc
,
DTS_MEASUREMENT_NOTIFICATION
=
0xdd
,
REPLY_DEBUG_CMD
=
0xf0
,
DEBUG_LOG_MSG
=
0xf7
,
...
...
@@ -550,7 +554,7 @@ enum iwl_time_event_type {
TE_WIDI_TX_SYNC
,
/* Channel Switch NoA */
TE_
P2P_GO_CSA_NOA
,
TE_
CHANNEL_SWITCH_PERIOD
,
TE_MAX
};
/* MAC_EVENT_TYPE_API_E_VER_1 */
...
...
@@ -1601,19 +1605,49 @@ enum iwl_sf_scenario {
#define SF_LONG_DELAY_AGING_TIMER 1000000
/* 1 Sec */
#define SF_CFG_DUMMY_NOTIF_OFF BIT(16)
/**
* Smart Fifo configuration command.
* @state: smart fifo state, types listed in iwl_sf_sate.
* @state: smart fifo state, types listed in
enum %
iwl_sf_sate.
* @watermark: Minimum allowed availabe free space in RXF for transient state.
* @long_delay_timeouts: aging and idle timer values for each scenario
* in long delay state.
* @full_on_timeouts: timer values for each scenario in full on state.
*/
struct
iwl_sf_cfg_cmd
{
enum
iwl_sf_state
state
;
__le32
state
;
__le32
watermark
[
SF_TRANSIENT_STATES_NUMBER
];
__le32
long_delay_timeouts
[
SF_NUM_SCENARIO
][
SF_NUM_TIMEOUT_TYPES
];
__le32
full_on_timeouts
[
SF_NUM_SCENARIO
][
SF_NUM_TIMEOUT_TYPES
];
}
__packed
;
/* SF_CFG_API_S_VER_2 */
/* DTS measurements */
enum
iwl_dts_measurement_flags
{
DTS_TRIGGER_CMD_FLAGS_TEMP
=
BIT
(
0
),
DTS_TRIGGER_CMD_FLAGS_VOLT
=
BIT
(
1
),
};
/**
* iwl_dts_measurement_cmd - request DTS temperature and/or voltage measurements
*
* @flags: indicates which measurements we want as specified in &enum
* iwl_dts_measurement_flags
*/
struct
iwl_dts_measurement_cmd
{
__le32
flags
;
}
__packed
;
/* TEMPERATURE_MEASUREMENT_TRIGGER_CMD_S */
/**
* iwl_dts_measurement_notif - notification received with the measurements
*
* @temp: the measured temperature
* @voltage: the measured voltage
*/
struct
iwl_dts_measurement_notif
{
__le32
temp
;
__le32
voltage
;
}
__packed
;
/* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */
#endif
/* __fw_api_h__ */
drivers/net/wireless/iwlwifi/mvm/fw.c
View file @
eb2eacf7
...
...
@@ -454,6 +454,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
for
(
i
=
0
;
i
<
IWL_MVM_STATION_COUNT
;
i
++
)
RCU_INIT_POINTER
(
mvm
->
fw_id_to_mac_id
[
i
],
NULL
);
/* reset quota debouncing buffer - 0xff will yield invalid data */
memset
(
&
mvm
->
last_quota_cmd
,
0xff
,
sizeof
(
mvm
->
last_quota_cmd
));
/* Add auxiliary station for scanning */
ret
=
iwl_mvm_add_aux_sta
(
mvm
);
if
(
ret
)
...
...
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
View file @
eb2eacf7
...
...
@@ -727,11 +727,6 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
!
force_assoc_off
)
{
u32
dtim_offs
;
/* Allow beacons to pass through as long as we are not
* associated, or we do not have dtim period information.
*/
cmd
.
filter_flags
|=
cpu_to_le32
(
MAC_FILTER_IN_BEACON
);
/*
* The DTIM count counts down, so when it is N that means N
* more beacon intervals happen until the DTIM TBTT. Therefore
...
...
@@ -765,6 +760,11 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
ctxt_sta
->
is_assoc
=
cpu_to_le32
(
1
);
}
else
{
ctxt_sta
->
is_assoc
=
cpu_to_le32
(
0
);
/* Allow beacons to pass through as long as we are not
* associated, or we do not have dtim period information.
*/
cmd
.
filter_flags
|=
cpu_to_le32
(
MAC_FILTER_IN_BEACON
);
}
ctxt_sta
->
bi
=
cpu_to_le32
(
vif
->
bss_conf
.
beacon_int
);
...
...
@@ -1234,13 +1234,13 @@ static void iwl_mvm_csa_count_down(struct iwl_mvm *mvm,
!
iwl_mvm_te_scheduled
(
&
mvmvif
->
time_event_data
)
&&
gp2
)
{
u32
rel_time
=
(
c
+
1
)
*
csa_vif
->
bss_conf
.
beacon_int
-
IWL_MVM_CHANNEL_SWITCH_TIME
;
IWL_MVM_CHANNEL_SWITCH_TIME
_GO
;
u32
apply_time
=
gp2
+
rel_time
*
1024
;
iwl_mvm_schedule_csa_
noa
(
mvm
,
csa_vif
,
IWL_MVM_CHANNEL_SWITCH_TIME
-
IWL_MVM_CHANNEL_SWITCH_MARGIN
,
apply_time
);
iwl_mvm_schedule_csa_
period
(
mvm
,
csa_vif
,
IWL_MVM_CHANNEL_SWITCH_TIME_GO
-
IWL_MVM_CHANNEL_SWITCH_MARGIN
,
apply_time
);
}
}
else
if
(
!
iwl_mvm_te_scheduled
(
&
mvmvif
->
time_event_data
))
{
/* we don't have CSA NoA scheduled yet, switch now */
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
View file @
eb2eacf7
...
...
@@ -327,7 +327,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IWL_UCODE_API
(
mvm
->
fw
->
ucode_ver
)
>=
9
&&
!
iwlwifi_mod_params
.
uapsd_disable
)
{
hw
->
flags
|=
IEEE80211_HW_SUPPORTS_UAPSD
;
hw
->
uapsd_queues
=
IWL_
UAPSD_AC_INFO
;
hw
->
uapsd_queues
=
IWL_
MVM_UAPSD_QUEUES
;
hw
->
uapsd_max_sp_len
=
IWL_UAPSD_MAX_SP
;
}
...
...
@@ -398,12 +398,14 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
else
hw
->
wiphy
->
flags
&=
~
WIPHY_FLAG_PS_ON_BY_DEFAULT
;
/* TODO: enable that only for firmwares that don't crash */
/* hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; */
hw
->
wiphy
->
max_sched_scan_ssids
=
PROBE_OPTION_MAX
;
hw
->
wiphy
->
max_match_sets
=
IWL_SCAN_MAX_PROFILES
;
/* we create the 802.11 header and zero length SSID IE. */
hw
->
wiphy
->
max_sched_scan_ie_len
=
SCAN_OFFLOAD_PROBE_REQ_SIZE
-
24
-
2
;
if
(
IWL_UCODE_API
(
mvm
->
fw
->
ucode_ver
)
>=
10
)
{
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
hw
->
wiphy
->
max_sched_scan_ssids
=
PROBE_OPTION_MAX
;
hw
->
wiphy
->
max_match_sets
=
IWL_SCAN_MAX_PROFILES
;
/* we create the 802.11 header and zero length SSID IE. */
hw
->
wiphy
->
max_sched_scan_ie_len
=
SCAN_OFFLOAD_PROBE_REQ_SIZE
-
24
-
2
;
}
hw
->
wiphy
->
features
|=
NL80211_FEATURE_P2P_GO_CTWIN
|
NL80211_FEATURE_LOW_PRIORITY_SCAN
|
...
...
@@ -668,8 +670,9 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
static
void
iwl_mvm_fw_error_dump
(
struct
iwl_mvm
*
mvm
)
void
iwl_mvm_fw_error_dump
(
struct
iwl_mvm
*
mvm
)
{
static
char
*
env
[]
=
{
"DRIVER=iwlwifi"
,
"EVENT=error_dump"
,
NULL
};
struct
iwl_fw_error_dump_file
*
dump_file
;
struct
iwl_fw_error_dump_data
*
dump_data
;
struct
iwl_fw_error_dump_info
*
dump_info
;
...
...
@@ -761,20 +764,16 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
file_len
+=
fw_error_dump
->
trans_ptr
->
len
;
dump_file
->
file_len
=
cpu_to_le32
(
file_len
);
mvm
->
fw_error_dump
=
fw_error_dump
;
/* notify the userspace about the error we had */
kobject_uevent_env
(
&
mvm
->
hw
->
wiphy
->
dev
.
kobj
,
KOBJ_CHANGE
,
env
);
}
#endif
static
void
iwl_mvm_restart_cleanup
(
struct
iwl_mvm
*
mvm
)
{
#ifdef CONFIG_IWLWIFI_DEBUGFS
static
char
*
env
[]
=
{
"DRIVER=iwlwifi"
,
"EVENT=error_dump"
,
NULL
};
iwl_mvm_fw_error_dump
(
mvm
);
/* notify the userspace about the error we had */
kobject_uevent_env
(
&
mvm
->
hw
->
wiphy
->
dev
.
kobj
,
KOBJ_CHANGE
,
env
);
#endif
iwl_trans_stop_device
(
mvm
->
trans
);
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
...
...
@@ -813,12 +812,11 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
mvm
->
rx_ba_sessions
=
0
;
}
static
int
iwl_mvm_mac_start
(
struct
ieee80211_hw
*
hw
)
int
__iwl_mvm_mac_start
(
struct
iwl_mvm
*
mvm
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
int
ret
;
mutex_lock
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
/* Clean up some internal and mac80211 state on restart */
if
(
test_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
))
...
...
@@ -835,6 +833,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
iwl_mvm_d0i3_enable_tx
(
mvm
,
NULL
);
}
return
ret
;
}
static
int
iwl_mvm_mac_start
(
struct
ieee80211_hw
*
hw
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
int
ret
;
mutex_lock
(
&
mvm
->
mutex
);
ret
=
__iwl_mvm_mac_start
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
return
ret
;
...
...
@@ -860,14 +868,9 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
mutex_unlock
(
&
mvm
->
mutex
);
}
static
void
iwl_mvm_mac_stop
(
struct
ieee80211_hw
*
hw
)
void
__iwl_mvm_mac_stop
(
struct
iwl_mvm
*
mvm
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
flush_work
(
&
mvm
->
d0i3_exit_work
);
flush_work
(
&
mvm
->
async_handlers_wk
);
mutex_lock
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
/* disallow low power states when the FW is down */
iwl_mvm_ref
(
mvm
,
IWL_MVM_REF_UCODE_DOWN
);
...
...
@@ -888,6 +891,19 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
/* the fw is stopped, the aux sta is dead: clean up driver state */
iwl_mvm_del_aux_sta
(
mvm
);
mvm
->
ucode_loaded
=
false
;
}
static
void
iwl_mvm_mac_stop
(
struct
ieee80211_hw
*
hw
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
flush_work
(
&
mvm
->
d0i3_exit_work
);
flush_work
(
&
mvm
->
async_handlers_wk
);
flush_work
(
&
mvm
->
fw_error_dump_wk
);
mutex_lock
(
&
mvm
->
mutex
);
__iwl_mvm_mac_stop
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
/*
...
...
@@ -1196,14 +1212,15 @@ static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mcast_filter_cmd
*
cmd
;
struct
netdev_hw_addr
*
addr
;
int
addr_count
=
netdev_hw_addr_list_count
(
mc_list
)
;
bool
pass_all
=
false
;
int
addr_count
;
bool
pass_all
;
int
len
;
if
(
addr_count
>
MAX_MCAST_FILTERING_ADDRESSES
)
{
pass_all
=
true
;
addr_count
=
netdev_hw_addr_list_count
(
mc_list
);
pass_all
=
addr_count
>
MAX_MCAST_FILTERING_ADDRESSES
||
IWL_MVM_FW_MCAST_FILTER_PASS_ALL
;
if
(
pass_all
)
addr_count
=
0
;
}
len
=
roundup
(
sizeof
(
*
cmd
)
+
addr_count
*
ETH_ALEN
,
4
);
cmd
=
kzalloc
(
len
,
GFP_ATOMIC
);
...
...
@@ -1403,28 +1420,6 @@ static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
}
#endif
static
void
iwl_mvm_teardown_tdls_peers
(
struct
iwl_mvm
*
mvm
)
{
struct
ieee80211_sta
*
sta
;
struct
iwl_mvm_sta
*
mvmsta
;
int
i
;
lockdep_assert_held
(
&
mvm
->
mutex
);
for
(
i
=
0
;
i
<
IWL_MVM_STATION_COUNT
;
i
++
)
{
sta
=
rcu_dereference_protected
(
mvm
->
fw_id_to_mac_id
[
i
],
lockdep_is_held
(
&
mvm
->
mutex
));
if
(
!
sta
||
IS_ERR
(
sta
)
||
!
sta
->
tdls
)
continue
;
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
ieee80211_tdls_oper_request
(
mvmsta
->
vif
,
sta
->
addr
,
NL80211_TDLS_TEARDOWN
,
WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
,
GFP_KERNEL
);
}
}
static
void
iwl_mvm_bss_info_changed_station
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_bss_conf
*
bss_conf
,
...
...
@@ -1544,11 +1539,6 @@ 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
|
BSS_CHANGED_P2P_PS
|
BSS_CHANGED_QOS
))
{
ret
=
iwl_mvm_power_update_mac
(
mvm
);
if
(
ret
)
IWL_ERR
(
mvm
,
"failed to update power mode
\n
"
);
}
if
(
changes
&
BSS_CHANGED_BEACON_INFO
)
{
...
...
@@ -1556,6 +1546,12 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
WARN_ON
(
iwl_mvm_enable_beacon_filter
(
mvm
,
vif
,
0
));
}
if
(
changes
&
(
BSS_CHANGED_PS
|
BSS_CHANGED_P2P_PS
|
BSS_CHANGED_QOS
))
{
ret
=
iwl_mvm_power_update_mac
(
mvm
);
if
(
ret
)
IWL_ERR
(
mvm
,
"failed to update power mode
\n
"
);
}
if
(
changes
&
BSS_CHANGED_TXPOWER
)
{
IWL_DEBUG_CALIB
(
mvm
,
"Changing TX Power to %d
\n
"
,
bss_conf
->
txpower
);
...
...
@@ -1721,7 +1717,7 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
return
;
if
(
changes
&
(
BSS_CHANGED_ERP_CTS_PROT
|
BSS_CHANGED_HT
|
BSS_CHANGED_BANDWIDTH
)
&&
BSS_CHANGED_BANDWIDTH
|
BSS_CHANGED_QOS
)
&&
iwl_mvm_mac_ctxt_changed
(
mvm
,
vif
,
false
,
NULL
))
IWL_ERR
(
mvm
,
"failed to update MAC %pM
\n
"
,
vif
->
addr
);
...
...
@@ -1952,48 +1948,6 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
mutex_unlock
(
&
mvm
->
mutex
);
}
int
iwl_mvm_tdls_sta_count
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
struct
ieee80211_sta
*
sta
;
struct
iwl_mvm_sta
*
mvmsta
;
int
count
=
0
;
int
i
;
lockdep_assert_held
(
&
mvm
->
mutex
);
for
(
i
=
0
;
i
<
IWL_MVM_STATION_COUNT
;
i
++
)
{
sta
=
rcu_dereference_protected
(
mvm
->
fw_id_to_mac_id
[
i
],
lockdep_is_held
(
&
mvm
->
mutex
));
if
(
!
sta
||
IS_ERR
(
sta
)
||
!
sta
->
tdls
)
continue
;
if
(
vif
)
{
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
if
(
mvmsta
->
vif
!=
vif
)
continue
;
}
count
++
;
}
return
count
;
}
static
void
iwl_mvm_recalc_tdls_state
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
bool
sta_added
)
{
int
tdls_sta_cnt
=
iwl_mvm_tdls_sta_count
(
mvm
,
vif
);
/*
* Disable ps when the first TDLS sta is added and re-enable it
* when the last TDLS sta is removed
*/
if
((
tdls_sta_cnt
==
1
&&
sta_added
)
||
(
tdls_sta_cnt
==
0
&&
!
sta_added
))
iwl_mvm_power_update_mac
(
mvm
);
}
static
int
iwl_mvm_mac_sta_state
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
...
...
@@ -2167,27 +2121,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_PREPARE_TX
);
}
static
void
iwl_mvm_mac_mgd_protect_tdls_discover
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
u32
duration
=
2
*
vif
->
bss_conf
.
dtim_period
*
vif
->
bss_conf
.
beacon_int
;
/*
* iwl_mvm_protect_session() reads directly from the device
* (the system time), so make sure it is available.
*/
if
(
iwl_mvm_ref_sync
(
mvm
,
IWL_MVM_REF_PROTECT_TDLS
))
return
;
mutex_lock
(
&
mvm
->
mutex
);
/* Protect the session to hear the TDLS setup response on the channel */
iwl_mvm_protect_session
(
mvm
,
vif
,
duration
,
duration
,
100
,
true
);
mutex_unlock
(
&
mvm
->
mutex
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_PROTECT_TDLS
);
}
static
int
iwl_mvm_mac_sched_scan_start
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_sched_scan_request
*
req
,
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
View file @
eb2eacf7
...
...
@@ -87,11 +87,11 @@
/* A TimeUnit is 1024 microsecond */
#define MSEC_TO_TU(_msec) (_msec*1000/1024)
/*
*
The CSA NoA is scheduled IWL_MVM_CHANNEL_SWITCH_TIME TUs before "beacon 0"
*
TBTT. This value should be
big enough to ensure that we switch in time.
/*
This value represents the number of TUs before CSA "beacon 0" TBTT
*
when the CSA time-event needs to be scheduled to start. It must be
* big enough to ensure that we switch in time.
*/
#define IWL_MVM_CHANNEL_SWITCH_TIME
40
#define IWL_MVM_CHANNEL_SWITCH_TIME
_GO
40
/*
* This value (in TUs) is used to fine tune the CSA NoA end time which should
...
...
@@ -180,10 +180,6 @@ enum iwl_power_scheme {
};
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
#define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
#define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2
#ifdef CONFIG_IWLWIFI_DEBUGFS
...
...
@@ -274,6 +270,8 @@ enum iwl_mvm_ref_type {
IWL_MVM_REF_TM_CMD
,
IWL_MVM_REF_EXIT_WORK
,
/* update debugfs.c when changing this */
IWL_MVM_REF_COUNT
,
};
...
...
@@ -649,6 +647,7 @@ struct iwl_mvm {
/* -1 for always, 0 for never, >0 for that many times */
s8
restart_fw
;
struct
work_struct
fw_error_dump_wk
;
struct
iwl_mvm_dump_ptrs
*
fw_error_dump
;
#ifdef CONFIG_IWLWIFI_LEDS
...
...
@@ -709,6 +708,8 @@ struct iwl_mvm {
*/
bool
temperature_test
;
/* Debug test temperature is enabled */
struct
iwl_time_quota_cmd
last_quota_cmd
;
#ifdef CONFIG_NL80211_TESTMODE
u32
noa_duration
;
struct
ieee80211_vif
*
noa_vif
;
...
...
@@ -788,6 +789,9 @@ struct iwl_rate_info {
u8
ieee
;
/* MAC header: IWL_RATE_6M_IEEE, etc. */
};
void
__iwl_mvm_mac_stop
(
struct
iwl_mvm
*
mvm
);
int
__iwl_mvm_mac_start
(
struct
iwl_mvm
*
mvm
);
/******************
* MVM Methods
******************/
...
...
@@ -1153,7 +1157,17 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
/* TDLS */
int
iwl_mvm_tdls_sta_count
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
void
iwl_mvm_teardown_tdls_peers
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_recalc_tdls_state
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
bool
sta_added
);
void
iwl_mvm_mac_mgd_protect_tdls_discover
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
);
void
iwl_mvm_nic_restart
(
struct
iwl_mvm
*
mvm
,
bool
fw_error
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
void
iwl_mvm_fw_error_dump
(
struct
iwl_mvm
*
mvm
);
#else
static
inline
void
iwl_mvm_fw_error_dump
(
struct
iwl_mvm
*
mvm
)
{}
#endif
#endif
/* __IWL_MVM_H__ */
drivers/net/wireless/iwlwifi/mvm/nvm.c
View file @
eb2eacf7
...
...
@@ -64,6 +64,7 @@
*****************************************************************************/
#include <linux/firmware.h>
#include "iwl-trans.h"
#include "iwl-csr.h"
#include "mvm.h"
#include "iwl-eeprom-parse.h"
#include "iwl-eeprom-read.h"
...
...
@@ -349,7 +350,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
/* Maximal size depends on HW family and step */
if
(
mvm
->
trans
->
cfg
->
device_family
!=
IWL_DEVICE_FAMILY_8000
)
max_section_size
=
IWL_MAX_NVM_SECTION_SIZE
;
else
if
(
(
mvm
->
trans
->
hw_rev
&
0xc
)
==
0
)
/* Family 8000 A-step */
else
if
(
CSR_HW_REV_STEP
(
mvm
->
trans
->
hw_rev
)
==
SILICON_A_STEP
)
max_section_size
=
IWL_MAX_NVM_8000A_SECTION_SIZE
;
else
/* Family 8000 B-step */
max_section_size
=
IWL_MAX_NVM_8000B_SECTION_SIZE
;
...
...
drivers/net/wireless/iwlwifi/mvm/ops.c
View file @
eb2eacf7
...
...
@@ -332,6 +332,8 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD
(
BCAST_FILTER_CMD
),
CMD
(
REPLY_SF_CFG_CMD
),
CMD
(
REPLY_BEACON_FILTERING_CMD
),
CMD
(
CMD_DTS_MEASUREMENT_TRIGGER
),
CMD
(
DTS_MEASUREMENT_NOTIFICATION
),
CMD
(
REPLY_THERMAL_MNG_BACKOFF
),
CMD
(
MAC_PM_POWER_TABLE
),
CMD
(
BT_COEX_CI
),
...
...
@@ -364,6 +366,8 @@ static u32 calc_min_backoff(struct iwl_trans *trans, const struct iwl_cfg *cfg)
return
0
;
}
static
void
iwl_mvm_fw_error_dump_wk
(
struct
work_struct
*
work
);
static
struct
iwl_op_mode
*
iwl_op_mode_mvm_start
(
struct
iwl_trans
*
trans
,
const
struct
iwl_cfg
*
cfg
,
const
struct
iwl_fw
*
fw
,
struct
dentry
*
dbgfs_dir
)
...
...
@@ -431,6 +435,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
INIT_WORK
(
&
mvm
->
roc_done_wk
,
iwl_mvm_roc_done_wk
);
INIT_WORK
(
&
mvm
->
sta_drained_wk
,
iwl_mvm_sta_drained_wk
);
INIT_WORK
(
&
mvm
->
d0i3_exit_work
,
iwl_mvm_d0i3_exit_work
);
INIT_WORK
(
&
mvm
->
fw_error_dump_wk
,
iwl_mvm_fw_error_dump_wk
);
spin_lock_init
(
&
mvm
->
d0i3_tx_lock
);
spin_lock_init
(
&
mvm
->
refs_lock
);
...
...
@@ -460,6 +465,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
trans_cfg
.
cmd_queue
=
IWL_MVM_CMD_QUEUE
;
trans_cfg
.
cmd_fifo
=
IWL_MVM_TX_FIFO_CMD
;
trans_cfg
.
scd_set_active
=
true
;
snprintf
(
mvm
->
hw
->
wiphy
->
fw_version
,
sizeof
(
mvm
->
hw
->
wiphy
->
fw_version
),
...
...
@@ -781,6 +787,16 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
module_put
(
THIS_MODULE
);
}
static
void
iwl_mvm_fw_error_dump_wk
(
struct
work_struct
*
work
)
{
struct
iwl_mvm
*
mvm
=
container_of
(
work
,
struct
iwl_mvm
,
fw_error_dump_wk
);
mutex_lock
(
&
mvm
->
mutex
);
iwl_mvm_fw_error_dump
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
}
void
iwl_mvm_nic_restart
(
struct
iwl_mvm
*
mvm
,
bool
fw_error
)
{
iwl_abort_notification_waits
(
&
mvm
->
notif_wait
);
...
...
@@ -846,6 +862,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
if
(
fw_error
&&
mvm
->
restart_fw
>
0
)
mvm
->
restart_fw
--
;
ieee80211_restart_hw
(
mvm
->
hw
);
}
else
if
(
fw_error
)
{
schedule_work
(
&
mvm
->
fw_error_dump_wk
);
}
}
...
...
drivers/net/wireless/iwlwifi/mvm/power.c
View file @
eb2eacf7
...
...
@@ -286,13 +286,28 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
return
true
;
}
static
bool
iwl_mvm_power_is_radar
(
struct
ieee80211_vif
*
vif
)
{
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_channel
*
chan
;
bool
radar_detect
=
false
;
rcu_read_lock
();
chanctx_conf
=
rcu_dereference
(
vif
->
chanctx_conf
);
WARN_ON
(
!
chanctx_conf
);
if
(
chanctx_conf
)
{
chan
=
chanctx_conf
->
def
.
chan
;
radar_detect
=
chan
->
flags
&
IEEE80211_CHAN_RADAR
;
}
rcu_read_unlock
();
return
radar_detect
;
}
static
void
iwl_mvm_power_build_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_mac_power_cmd
*
cmd
)
{
struct
ieee80211_hw
*
hw
=
mvm
->
hw
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_channel
*
chan
;
int
dtimper
,
dtimper_msec
;
int
keep_alive
;
bool
radar_detect
=
false
;
...
...
@@ -301,7 +316,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
cmd
->
id_and_color
=
cpu_to_le32
(
FW_CMD_ID_AND_COLOR
(
mvmvif
->
id
,
mvmvif
->
color
));
dtimper
=
hw
->
conf
.
ps_dtim_period
?:
1
;
dtimper
=
vif
->
bss_conf
.
dtim_period
;
/*
* Regardless of power management state the driver must set
...
...
@@ -321,7 +336,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_POWER_SAVE_ENA_MSK
);
if
(
!
vif
->
bss_conf
.
ps
||
iwl_mvm_vif_low_latency
(
mvmvif
)
||
!
mvmvif
->
pm_enabled
)
!
mvmvif
->
pm_enabled
||
iwl_mvm_tdls_sta_count
(
mvm
,
vif
)
)
return
;
cmd
->
flags
|=
cpu_to_le16
(
POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK
);
...
...
@@ -334,14 +349,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
}
/* Check if radar detection is required on current channel */
rcu_read_lock
();
chanctx_conf
=
rcu_dereference
(
vif
->
chanctx_conf
);
WARN_ON
(
!
chanctx_conf
);
if
(
chanctx_conf
)
{
chan
=
chanctx_conf
->
def
.
chan
;
radar_detect
=
chan
->
flags
&
IEEE80211_CHAN_RADAR
;
}
rcu_read_unlock
();
radar_detect
=
iwl_mvm_power_is_radar
(
vif
);
/* Check skip over DTIM conditions */
if
(
!
radar_detect
&&
(
dtimper
<=
10
)
&&
...
...
@@ -502,8 +510,6 @@ struct iwl_power_vifs {
bool
bss_active
;
bool
ap_active
;
bool
monitor_active
;
bool
bss_tdls
;
bool
p2p_tdls
;
};
static
void
iwl_mvm_power_disable_pm_iterator
(
void
*
_data
,
u8
*
mac
,
...
...
@@ -558,8 +564,6 @@ static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
/* only a single MAC of the same type */
WARN_ON
(
power_iterator
->
p2p_vif
);
power_iterator
->
p2p_vif
=
vif
;
power_iterator
->
p2p_tdls
=
!!
iwl_mvm_tdls_sta_count
(
power_iterator
->
mvm
,
vif
);
if
(
mvmvif
->
phy_ctxt
)
if
(
mvmvif
->
phy_ctxt
->
id
<
MAX_PHYS
)
power_iterator
->
p2p_active
=
true
;
...
...
@@ -569,8 +573,6 @@ static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
/* only a single MAC of the same type */
WARN_ON
(
power_iterator
->
bss_vif
);
power_iterator
->
bss_vif
=
vif
;
power_iterator
->
bss_tdls
=
!!
iwl_mvm_tdls_sta_count
(
power_iterator
->
mvm
,
vif
);
if
(
mvmvif
->
phy_ctxt
)
if
(
mvmvif
->
phy_ctxt
->
id
<
MAX_PHYS
)
power_iterator
->
bss_active
=
true
;
...
...
@@ -613,15 +615,13 @@ static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
ap_mvmvif
=
iwl_mvm_vif_from_mac80211
(
vifs
->
ap_vif
);
/* enable PM on bss if bss stand alone */
if
(
vifs
->
bss_active
&&
!
vifs
->
p2p_active
&&
!
vifs
->
ap_active
&&
!
vifs
->
bss_tdls
)
{
if
(
vifs
->
bss_active
&&
!
vifs
->
p2p_active
&&
!
vifs
->
ap_active
)
{
bss_mvmvif
->
pm_enabled
=
true
;
return
;
}
/* enable PM on p2p if p2p stand alone */
if
(
vifs
->
p2p_active
&&
!
vifs
->
bss_active
&&
!
vifs
->
ap_active
&&
!
vifs
->
p2p_tdls
)
{
if
(
vifs
->
p2p_active
&&
!
vifs
->
bss_active
&&
!
vifs
->
ap_active
)
{
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_P2P_PM
)
p2p_mvmvif
->
pm_enabled
=
true
;
return
;
...
...
@@ -962,17 +962,22 @@ int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
iwl_mvm_power_build_cmd
(
mvm
,
vif
,
&
cmd
);
if
(
enable
)
{
/* configure skip over dtim up to 300 msec */
int
dtimper
=
mvm
->
hw
->
conf
.
ps_dtim_period
?:
1
;
int
dtimper_msec
=
dtimper
*
vif
->
bss_conf
.
beacon_int
;
/* configure skip over dtim up to 306TU - 314 msec */
int
dtimper
=
vif
->
bss_conf
.
dtim_period
?:
1
;
int
dtimper_tu
=
dtimper
*
vif
->
bss_conf
.
beacon_int
;
bool
radar_detect
=
iwl_mvm_power_is_radar
(
vif
);
if
(
WARN_ON
(
!
dtimper_
msec
))
if
(
WARN_ON
(
!
dtimper_
tu
))
return
0
;
cmd
.
skip_dtim_periods
=
300
/
dtimper_msec
;
if
(
cmd
.
skip_dtim_periods
)
cmd
.
flags
|=
cpu_to_le16
(
POWER_FLAGS_SKIP_OVER_DTIM_MSK
);
/* Check skip over DTIM conditions */
/* TODO: check that multicast wake lock is off */
if
(
!
radar_detect
&&
(
dtimper
<
10
))
{
cmd
.
skip_dtim_periods
=
306
/
dtimper_tu
;
if
(
cmd
.
skip_dtim_periods
)
cmd
.
flags
|=
cpu_to_le16
(
POWER_FLAGS_SKIP_OVER_DTIM_MSK
);
}
}
iwl_mvm_power_log
(
mvm
,
&
cmd
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
...
...
drivers/net/wireless/iwlwifi/mvm/quota.c
View file @
eb2eacf7
...
...
@@ -175,12 +175,14 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
struct
ieee80211_vif
*
disabled_vif
)
{
struct
iwl_time_quota_cmd
cmd
=
{};
int
i
,
idx
,
ret
,
num_active_macs
,
quota
,
quota_rem
,
n_non_lowlat
;
int
i
,
idx
,
err
,
num_active_macs
,
quota
,
quota_rem
,
n_non_lowlat
;
struct
iwl_mvm_quota_iterator_data
data
=
{
.
n_interfaces
=
{},
.
colors
=
{
-
1
,
-
1
,
-
1
,
-
1
},
.
disabled_vif
=
disabled_vif
,
};
struct
iwl_time_quota_cmd
*
last
=
&
mvm
->
last_quota_cmd
;
bool
send
=
false
;
lockdep_assert_held
(
&
mvm
->
mutex
);
...
...
@@ -293,15 +295,33 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
/* check that we have non-zero quota for all valid bindings */
for
(
i
=
0
;
i
<
MAX_BINDINGS
;
i
++
)
{
if
(
cmd
.
quotas
[
i
].
id_and_color
!=
last
->
quotas
[
i
].
id_and_color
)
send
=
true
;
if
(
cmd
.
quotas
[
i
].
max_duration
!=
last
->
quotas
[
i
].
max_duration
)
send
=
true
;
if
(
abs
((
int
)
le32_to_cpu
(
cmd
.
quotas
[
i
].
quota
)
-
(
int
)
le32_to_cpu
(
last
->
quotas
[
i
].
quota
))
>
IWL_MVM_QUOTA_THRESHOLD
)
send
=
true
;
if
(
cmd
.
quotas
[
i
].
id_and_color
==
cpu_to_le32
(
FW_CTXT_INVALID
))
continue
;
WARN_ONCE
(
cmd
.
quotas
[
i
].
quota
==
0
,
"zero quota on binding %d
\n
"
,
i
);
}
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
TIME_QUOTA_CMD
,
0
,
sizeof
(
cmd
),
&
cmd
);
if
(
ret
)
IWL_ERR
(
mvm
,
"Failed to send quota: %d
\n
"
,
ret
);
return
ret
;
if
(
!
send
)
{
/* don't send a practically unchanged command, the firmware has
* to re-initialize a lot of state and that can have an adverse
* impact on it
*/
return
0
;
}
err
=
iwl_mvm_send_cmd_pdu
(
mvm
,
TIME_QUOTA_CMD
,
0
,
sizeof
(
cmd
),
&
cmd
);
if
(
err
)
IWL_ERR
(
mvm
,
"Failed to send quota: %d
\n
"
,
err
);
else
mvm
->
last_quota_cmd
=
cmd
;
return
err
;
}
drivers/net/wireless/iwlwifi/mvm/rs.c
View file @
eb2eacf7
...
...
@@ -505,10 +505,10 @@ static const char *rs_pretty_lq_type(enum iwl_table_type type)
static
inline
void
rs_dump_rate
(
struct
iwl_mvm
*
mvm
,
const
struct
rs_rate
*
rate
,
const
char
*
prefix
)
{
IWL_DEBUG_RATE
(
mvm
,
"%s: (%s: %d) ANT: %s BW: %d SGI: %d
\n
"
,
IWL_DEBUG_RATE
(
mvm
,
"%s: (%s: %d) ANT: %s BW: %d SGI: %d
LDPC: %d
\n
"
,
prefix
,
rs_pretty_lq_type
(
rate
->
type
),
rate
->
index
,
rs_pretty_ant
(
rate
->
ant
),
rate
->
bw
,
rate
->
sgi
);
rate
->
bw
,
rate
->
sgi
,
rate
->
ldpc
);
}
static
void
rs_rate_scale_clear_window
(
struct
iwl_rate_scale_data
*
window
)
...
...
@@ -672,8 +672,10 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
return
-
EINVAL
;
if
(
tbl
->
column
!=
RS_COLUMN_INVALID
)
{
lq_sta
->
tx_stats
[
tbl
->
column
][
scale_index
].
total
+=
attempts
;
lq_sta
->
tx_stats
[
tbl
->
column
][
scale_index
].
success
+=
successes
;
struct
lq_sta_pers
*
pers
=
&
lq_sta
->
pers
;
pers
->
tx_stats
[
tbl
->
column
][
scale_index
].
total
+=
attempts
;
pers
->
tx_stats
[
tbl
->
column
][
scale_index
].
success
+=
successes
;
}
/* Select window for current tx bit rate */
...
...
@@ -742,6 +744,8 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
ucode_rate
|=
rate
->
bw
;
if
(
rate
->
sgi
)
ucode_rate
|=
RATE_MCS_SGI_MSK
;
if
(
rate
->
ldpc
)
ucode_rate
|=
RATE_MCS_LDPC_MSK
;
return
ucode_rate
;
}
...
...
@@ -779,6 +783,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
/* HT or VHT */
if
(
ucode_rate
&
RATE_MCS_SGI_MSK
)
rate
->
sgi
=
true
;
if
(
ucode_rate
&
RATE_MCS_LDPC_MSK
)
rate
->
ldpc
=
true
;
rate
->
bw
=
ucode_rate
&
RATE_MCS_CHAN_WIDTH_MSK
;
...
...
@@ -965,13 +971,13 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
rate
->
index
>
IWL_RATE_MCS_9_INDEX
);
rate
->
index
=
rs_ht_to_legacy
[
rate
->
index
];
rate
->
ldpc
=
false
;
}
else
{
/* Downgrade to SISO with same MCS if in MIMO */
rate
->
type
=
is_vht_mimo2
(
rate
)
?
LQ_VHT_SISO
:
LQ_HT_SISO
;
}
if
(
num_of_ant
(
rate
->
ant
)
>
1
)
rate
->
ant
=
first_antenna
(
mvm
->
fw
->
valid_tx_ant
);
...
...
@@ -1621,6 +1627,7 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
}
rate
->
bw
=
rs_bw_from_sta_bw
(
sta
);
rate
->
ldpc
=
lq_sta
->
ldpc
;
search_tbl
->
column
=
col_id
;
rs_set_expected_tpt_table
(
lq_sta
,
search_tbl
);
...
...
@@ -2031,18 +2038,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
return
;
}
/* force user max rate if set by user */
if
((
lq_sta
->
max_rate_idx
!=
-
1
)
&&
(
lq_sta
->
max_rate_idx
<
index
))
{
index
=
lq_sta
->
max_rate_idx
;
update_lq
=
1
;
window
=
&
(
tbl
->
win
[
index
]);
IWL_DEBUG_RATE
(
mvm
,
"Forcing user max rate %d
\n
"
,
index
);
goto
lq_update
;
}
/* TODO: handle rate_idx_mask and rate_idx_mcs_mask */
window
=
&
(
tbl
->
win
[
index
]);
/*
...
...
@@ -2130,10 +2126,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
low
=
high_low
&
0xff
;
high
=
(
high_low
>>
8
)
&
0xff
;
/* If user set max rate, dont allow higher than user constrain */
if
((
lq_sta
->
max_rate_idx
!=
-
1
)
&&
(
lq_sta
->
max_rate_idx
<
high
))
high
=
IWL_RATE_INVALID
;
/* TODO: handle rate_idx_mask and rate_idx_mcs_mask */
sr
=
window
->
success_ratio
;
...
...
@@ -2342,6 +2335,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
rate
->
index
=
i
;
rate
->
ant
=
first_antenna
(
valid_tx_ant
);
rate
->
sgi
=
false
;
rate
->
ldpc
=
false
;
rate
->
bw
=
RATE_MCS_CHAN_WIDTH_20
;
if
(
band
==
IEEE80211_BAND_5GHZ
)
rate
->
type
=
LQ_LEGACY_A
;
...
...
@@ -2364,23 +2358,13 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
struct
ieee80211_tx_rate_control
*
txrc
)
{
struct
sk_buff
*
skb
=
txrc
->
skb
;
struct
ieee80211_supported_band
*
sband
=
txrc
->
sband
;
struct
iwl_op_mode
*
op_mode
__maybe_unused
=
(
struct
iwl_op_mode
*
)
mvm_r
;
struct
iwl_mvm
*
mvm
__maybe_unused
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
struct
iwl_lq_sta
*
lq_sta
=
mvm_sta
;
/* Get max rate if user set max rate */
if
(
lq_sta
)
{
lq_sta
->
max_rate_idx
=
txrc
->
max_rate_idx
;
if
((
sband
->
band
==
IEEE80211_BAND_5GHZ
)
&&
(
lq_sta
->
max_rate_idx
!=
-
1
))
lq_sta
->
max_rate_idx
+=
IWL_FIRST_OFDM_RATE
;
if
((
lq_sta
->
max_rate_idx
<
0
)
||
(
lq_sta
->
max_rate_idx
>=
IWL_RATE_COUNT
))
lq_sta
->
max_rate_idx
=
-
1
;
}
/* TODO: handle rate_idx_mask and rate_idx_mcs_mask */
/* Treat uninitialized rate scaling data same as non-existing. */
if
(
lq_sta
&&
!
lq_sta
->
pers
.
drv
)
{
...
...
@@ -2581,7 +2565,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
* previous packets? Need to have IEEE 802.1X auth succeed immediately
* after assoc.. */
lq_sta
->
max_rate_idx
=
-
1
;
lq_sta
->
missed_rate_counter
=
IWL_MISSED_RATE_MAX
;
lq_sta
->
band
=
sband
->
band
;
/*
...
...
@@ -2610,9 +2593,16 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
lq_sta
->
active_mimo2_rate
<<=
IWL_FIRST_OFDM_RATE
;
lq_sta
->
is_vht
=
false
;
if
(
mvm
->
cfg
->
ht_params
->
ldpc
&&
(
ht_cap
->
cap
&
IEEE80211_HT_CAP_LDPC_CODING
))
lq_sta
->
ldpc
=
true
;
}
else
{
rs_vht_set_enabled_rates
(
sta
,
vht_cap
,
lq_sta
);
lq_sta
->
is_vht
=
true
;
if
(
mvm
->
cfg
->
ht_params
->
ldpc
&&
(
vht_cap
->
cap
&
IEEE80211_VHT_CAP_RXLDPC
))
lq_sta
->
ldpc
=
true
;
}
lq_sta
->
max_legacy_rate_idx
=
find_last_bit
(
&
lq_sta
->
active_legacy_rate
,
...
...
@@ -2622,11 +2612,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
lq_sta
->
max_mimo2_rate_idx
=
find_last_bit
(
&
lq_sta
->
active_mimo2_rate
,
BITS_PER_LONG
);
IWL_DEBUG_RATE
(
mvm
,
"RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d
\n
"
,
IWL_DEBUG_RATE
(
mvm
,
"RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d
\n
"
,
lq_sta
->
active_legacy_rate
,
lq_sta
->
active_siso_rate
,
lq_sta
->
active_mimo2_rate
,
lq_sta
->
is_vht
);
lq_sta
->
is_vht
,
lq_sta
->
ldpc
);
IWL_DEBUG_RATE
(
mvm
,
"MAX RATE: LEGACY=%d SISO=%d MIMO2=%d
\n
"
,
lq_sta
->
max_legacy_rate_idx
,
lq_sta
->
max_siso_rate_idx
,
...
...
@@ -3032,8 +3023,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
(
is_ht20
(
rate
))
?
"20MHz"
:
(
is_ht40
(
rate
))
?
"40MHz"
:
(
is_ht80
(
rate
))
?
"80Mhz"
:
"BAD BW"
);
desc
+=
sprintf
(
buff
+
desc
,
" %s %s
\n
"
,
desc
+=
sprintf
(
buff
+
desc
,
" %s %s
%s
\n
"
,
(
rate
->
sgi
)
?
"SGI"
:
"NGI"
,
(
rate
->
ldpc
)
?
"LDPC"
:
"BCC"
,
(
lq_sta
->
is_agg
)
?
"AGG on"
:
""
);
}
desc
+=
sprintf
(
buff
+
desc
,
"last tx rate=0x%X
\n
"
,
...
...
@@ -3181,7 +3173,7 @@ static ssize_t rs_sta_dbgfs_drv_tx_stats_read(struct file *file,
"%s,"
,
column_name
[
col
]);
for
(
rate
=
0
;
rate
<
IWL_RATE_COUNT
;
rate
++
)
{
stats
=
&
(
lq_sta
->
tx_stats
[
col
][
rate
]);
stats
=
&
(
lq_sta
->
pers
.
tx_stats
[
col
][
rate
]);
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"%llu/%llu,"
,
stats
->
success
,
...
...
@@ -3200,7 +3192,7 @@ static ssize_t rs_sta_dbgfs_drv_tx_stats_write(struct file *file,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_lq_sta
*
lq_sta
=
file
->
private_data
;
memset
(
lq_sta
->
tx_stats
,
0
,
sizeof
(
lq_sta
->
tx_stats
));
memset
(
lq_sta
->
pers
.
tx_stats
,
0
,
sizeof
(
lq_sta
->
pers
.
tx_stats
));
return
count
;
}
...
...
drivers/net/wireless/iwlwifi/mvm/rs.h
View file @
eb2eacf7
...
...
@@ -207,6 +207,7 @@ struct rs_rate {
u8
ant
;
u32
bw
;
bool
sgi
;
bool
ldpc
;
};
...
...
@@ -329,10 +330,9 @@ struct iwl_lq_sta {
*/
u64
last_tx
;
bool
is_vht
;
bool
ldpc
;
/* LDPC Rx is supported by the STA */
enum
ieee80211_band
band
;
struct
rs_rate_stats
tx_stats
[
RS_COLUMN_COUNT
][
IWL_RATE_COUNT
];
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
unsigned
long
active_legacy_rate
;
unsigned
long
active_siso_rate
;
...
...
@@ -343,7 +343,6 @@ struct iwl_lq_sta {
u8
max_siso_rate_idx
;
u8
max_mimo2_rate_idx
;
s8
max_rate_idx
;
/* Max rate set by user */
u8
missed_rate_counter
;
struct
iwl_lq_cmd
lq
;
...
...
@@ -361,11 +360,14 @@ struct iwl_lq_sta {
int
tpc_reduce
;
/* persistent fields - initialized only once - keep last! */
struct
{
struct
lq_sta_pers
{
#ifdef CONFIG_MAC80211_DEBUGFS
u32
dbg_fixed_rate
;
u8
dbg_fixed_txp_reduction
;
#endif
u8
chains
;
s8
chain_signal
[
IEEE80211_MAX_CHAINS
];
struct
rs_rate_stats
tx_stats
[
RS_COLUMN_COUNT
][
IWL_RATE_COUNT
];
struct
iwl_mvm
*
drv
;
}
pers
;
};
...
...
drivers/net/wireless/iwlwifi/mvm/rx.c
View file @
eb2eacf7
...
...
@@ -151,13 +151,13 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
le32_to_cpu
(
phy_info
->
non_cfg_phy
[
IWL_RX_INFO_ENERGY_ANT_ABC_IDX
]);
energy_a
=
(
val
&
IWL_RX_INFO_ENERGY_ANT_A_MSK
)
>>
IWL_RX_INFO_ENERGY_ANT_A_POS
;
energy_a
=
energy_a
?
-
energy_a
:
-
256
;
energy_a
=
energy_a
?
-
energy_a
:
S8_MIN
;
energy_b
=
(
val
&
IWL_RX_INFO_ENERGY_ANT_B_MSK
)
>>
IWL_RX_INFO_ENERGY_ANT_B_POS
;
energy_b
=
energy_b
?
-
energy_b
:
-
256
;
energy_b
=
energy_b
?
-
energy_b
:
S8_MIN
;
energy_c
=
(
val
&
IWL_RX_INFO_ENERGY_ANT_C_MSK
)
>>
IWL_RX_INFO_ENERGY_ANT_C_POS
;
energy_c
=
energy_c
?
-
energy_c
:
-
256
;
energy_c
=
energy_c
?
-
energy_c
:
S8_MIN
;
max_energy
=
max
(
energy_a
,
energy_b
);
max_energy
=
max
(
max_energy
,
energy_c
);
...
...
drivers/net/wireless/iwlwifi/mvm/scan.c
View file @
eb2eacf7
...
...
@@ -160,8 +160,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
static
u16
iwl_mvm_get_active_dwell
(
enum
ieee80211_band
band
,
int
n_ssids
)
{
if
(
band
==
IEEE80211_BAND_2GHZ
)
return
3
0
+
3
*
(
n_ssids
+
1
);
return
2
0
+
2
*
(
n_ssids
+
1
);
return
2
0
+
3
*
(
n_ssids
+
1
);
return
1
0
+
2
*
(
n_ssids
+
1
);
}
static
u16
iwl_mvm_get_passive_dwell
(
enum
ieee80211_band
band
)
...
...
drivers/net/wireless/iwlwifi/mvm/sf.c
View file @
eb2eacf7
...
...
@@ -174,11 +174,15 @@ static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
enum
iwl_sf_state
new_state
)
{
struct
iwl_sf_cfg_cmd
sf_cmd
=
{
.
state
=
new_state
,
.
state
=
cpu_to_le32
(
new_state
)
,
};
struct
ieee80211_sta
*
sta
;
int
ret
=
0
;
if
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF
&&
mvm
->
cfg
->
disable_dummy_notification
)
sf_cmd
.
state
|=
cpu_to_le32
(
SF_CFG_DUMMY_NOTIF_OFF
);
/*
* If an associated AP sta changed its antenna configuration, the state
* will remain FULL_ON but SF parameters need to be reconsidered.
...
...
drivers/net/wireless/iwlwifi/mvm/sta.c
View file @
eb2eacf7
...
...
@@ -948,8 +948,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
}
tid_data
->
ssn
=
0xffff
;
tid_data
->
state
=
IWL_AGG_OFF
;
mvm
->
queue_to_mac80211
[
txq_id
]
=
IWL_INVALID_MAC80211_QUEUE
;
spin_unlock_bh
(
&
mvmsta
->
lock
);
ieee80211_stop_tx_ba_cb_irqsafe
(
vif
,
sta
->
addr
,
tid
);
iwl_mvm_sta_tx_agg
(
mvm
,
sta
,
tid
,
txq_id
,
false
);
iwl_trans_txq_disable
(
mvm
->
trans
,
txq_id
,
true
);
/* fall through */
return
0
;
case
IWL_AGG_STARTING
:
case
IWL_EMPTYING_HW_QUEUE_ADDBA
:
/*
...
...
@@ -1003,6 +1011,8 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if
(
iwl_mvm_flush_tx_path
(
mvm
,
BIT
(
txq_id
),
true
))
IWL_ERR
(
mvm
,
"Couldn't flush the AGG queue
\n
"
);
iwl_mvm_sta_tx_agg
(
mvm
,
sta
,
tid
,
txq_id
,
false
);
iwl_trans_txq_disable
(
mvm
->
trans
,
tid_data
->
txq_id
,
true
);
}
...
...
drivers/net/wireless/iwlwifi/mvm/tdls.c
0 → 100644
View file @
eb2eacf7
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2014 Intel Mobile Communications GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2014 Intel Mobile Communications GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "mvm.h"
#include "time-event.h"
void
iwl_mvm_teardown_tdls_peers
(
struct
iwl_mvm
*
mvm
)
{
struct
ieee80211_sta
*
sta
;
struct
iwl_mvm_sta
*
mvmsta
;
int
i
;
lockdep_assert_held
(
&
mvm
->
mutex
);
for
(
i
=
0
;
i
<
IWL_MVM_STATION_COUNT
;
i
++
)
{
sta
=
rcu_dereference_protected
(
mvm
->
fw_id_to_mac_id
[
i
],
lockdep_is_held
(
&
mvm
->
mutex
));
if
(
!
sta
||
IS_ERR
(
sta
)
||
!
sta
->
tdls
)
continue
;
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
ieee80211_tdls_oper_request
(
mvmsta
->
vif
,
sta
->
addr
,
NL80211_TDLS_TEARDOWN
,
WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
,
GFP_KERNEL
);
}
}
int
iwl_mvm_tdls_sta_count
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
struct
ieee80211_sta
*
sta
;
struct
iwl_mvm_sta
*
mvmsta
;
int
count
=
0
;
int
i
;
lockdep_assert_held
(
&
mvm
->
mutex
);
for
(
i
=
0
;
i
<
IWL_MVM_STATION_COUNT
;
i
++
)
{
sta
=
rcu_dereference_protected
(
mvm
->
fw_id_to_mac_id
[
i
],
lockdep_is_held
(
&
mvm
->
mutex
));
if
(
!
sta
||
IS_ERR
(
sta
)
||
!
sta
->
tdls
)
continue
;
if
(
vif
)
{
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
if
(
mvmsta
->
vif
!=
vif
)
continue
;
}
count
++
;
}
return
count
;
}
void
iwl_mvm_recalc_tdls_state
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
bool
sta_added
)
{
int
tdls_sta_cnt
=
iwl_mvm_tdls_sta_count
(
mvm
,
vif
);
/*
* Disable ps when the first TDLS sta is added and re-enable it
* when the last TDLS sta is removed
*/
if
((
tdls_sta_cnt
==
1
&&
sta_added
)
||
(
tdls_sta_cnt
==
0
&&
!
sta_added
))
iwl_mvm_power_update_mac
(
mvm
);
}
void
iwl_mvm_mac_mgd_protect_tdls_discover
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
u32
duration
=
2
*
vif
->
bss_conf
.
dtim_period
*
vif
->
bss_conf
.
beacon_int
;
/*
* iwl_mvm_protect_session() reads directly from the device
* (the system time), so make sure it is available.
*/
if
(
iwl_mvm_ref_sync
(
mvm
,
IWL_MVM_REF_PROTECT_TDLS
))
return
;
mutex_lock
(
&
mvm
->
mutex
);
/* Protect the session to hear the TDLS setup response on the channel */
iwl_mvm_protect_session
(
mvm
,
vif
,
duration
,
duration
,
100
,
true
);
mutex_unlock
(
&
mvm
->
mutex
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_PROTECT_TDLS
);
}
drivers/net/wireless/iwlwifi/mvm/time-event.c
View file @
eb2eacf7
...
...
@@ -700,9 +700,9 @@ void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
iwl_mvm_roc_finished
(
mvm
);
}
int
iwl_mvm_schedule_csa_
noa
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
u32
duration
,
u32
apply_time
)
int
iwl_mvm_schedule_csa_
period
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
u32
duration
,
u32
apply_time
)
{
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
struct
iwl_mvm_time_event_data
*
te_data
=
&
mvmvif
->
time_event_data
;
...
...
@@ -711,14 +711,14 @@ int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm,
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
te_data
->
running
)
{
IWL_DEBUG_TE
(
mvm
,
"CS
NOA
is already scheduled
\n
"
);
IWL_DEBUG_TE
(
mvm
,
"CS
period
is already scheduled
\n
"
);
return
-
EBUSY
;
}
time_cmd
.
action
=
cpu_to_le32
(
FW_CTXT_ACTION_ADD
);
time_cmd
.
id_and_color
=
cpu_to_le32
(
FW_CMD_ID_AND_COLOR
(
mvmvif
->
id
,
mvmvif
->
color
));
time_cmd
.
id
=
cpu_to_le32
(
TE_
P2P_GO_CSA_NOA
);
time_cmd
.
id
=
cpu_to_le32
(
TE_
CHANNEL_SWITCH_PERIOD
);
time_cmd
.
apply_time
=
cpu_to_le32
(
apply_time
);
time_cmd
.
max_frags
=
TE_V2_FRAG_NONE
;
time_cmd
.
duration
=
cpu_to_le32
(
duration
);
...
...
drivers/net/wireless/iwlwifi/mvm/time-event.h
View file @
eb2eacf7
...
...
@@ -219,7 +219,7 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
void
iwl_mvm_roc_done_wk
(
struct
work_struct
*
wk
);
/**
* iwl_mvm_schedule_csa_
noa - request NoA for channel switch
* iwl_mvm_schedule_csa_
period - request channel switch absence period
* @mvm: the mvm component
* @vif: the virtual interface for which the channel switch is issued
* @duration: the duration of the NoA in TU.
...
...
@@ -228,9 +228,9 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk);
* This function is used to schedule NoA time event and is used to perform
* the channel switch flow.
*/
int
iwl_mvm_schedule_csa_
noa
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
u32
duration
,
u32
apply_time
);
int
iwl_mvm_schedule_csa_
period
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
u32
duration
,
u32
apply_time
);
/**
* iwl_mvm_te_scheduled - check if the fw received the TE cmd
...
...
drivers/net/wireless/iwlwifi/mvm/tt.c
View file @
eb2eacf7
...
...
@@ -69,275 +69,99 @@
#include "iwl-csr.h"
#include "iwl-prph.h"
#define OTP_DTS_DIODE_DEVIATION 96
/*in words*/
/* VBG - Voltage Band Gap error data (temperature offset) */
#define OTP_WP_DTS_VBG (OTP_DTS_DIODE_DEVIATION + 2)
#define MEAS_VBG_MIN_VAL 2300
#define MEAS_VBG_MAX_VAL 3000
#define MEAS_VBG_DEFAULT_VAL 2700
#define DTS_DIODE_VALID(flags) (flags & DTS_DIODE_REG_FLAGS_PASS_ONCE)
#define MIN_TEMPERATURE 0
#define MAX_TEMPERATURE 125
#define TEMPERATURE_ERROR (MAX_TEMPERATURE + 1)
#define PTAT_DIGITAL_VALUE_MIN_VALUE 0
#define PTAT_DIGITAL_VALUE_MAX_VALUE 0xFF
#define DTS_VREFS_NUM 5
static
inline
u32
DTS_DIODE_GET_VREFS_ID
(
u32
flags
)
{
return
(
flags
&
DTS_DIODE_REG_FLAGS_VREFS_ID
)
>>
DTS_DIODE_REG_FLAGS_VREFS_ID_POS
;
}
#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ
#define CALC_VREFS_MIN_DIFF 43
#define CALC_VREFS_MAX_DIFF 51
#define CALC_LUT_SIZE (1 + CALC_VREFS_MAX_DIFF - CALC_VREFS_MIN_DIFF)
#define CALC_LUT_INDEX_OFFSET CALC_VREFS_MIN_DIFF
#define CALC_TEMPERATURE_RESULT_SHIFT_OFFSET 23
/*
* @digital_value: The diode's digital-value sampled (temperature/voltage)
* @vref_low: The lower voltage-reference (the vref just below the diode's
* sampled digital-value)
* @vref_high: The higher voltage-reference (the vref just above the diode's
* sampled digital-value)
* @flags: bits[1:0]: The ID of the Vrefs pair (lowVref,highVref)
* bits[6:2]: Reserved.
* bits[7:7]: Indicates completion of at least 1 successful sample
* since last DTS reset.
*/
struct
iwl_mvm_dts_diode_bits
{
u8
digital_value
;
u8
vref_low
;
u8
vref_high
;
u8
flags
;
}
__packed
;
union
dts_diode_results
{
u32
reg_value
;
struct
iwl_mvm_dts_diode_bits
bits
;
}
__packed
;
static
s16
iwl_mvm_dts_get_volt_band_gap
(
struct
iwl_mvm
*
mvm
)
static
void
iwl_mvm_enter_ctkill
(
struct
iwl_mvm
*
mvm
)
{
struct
iwl_nvm_section
calib_sec
;
const
__le16
*
calib
;
u16
vbg
;
/* TODO: move parsing to NVM code */
calib_sec
=
mvm
->
nvm_sections
[
NVM_SECTION_TYPE_CALIBRATION
];
calib
=
(
__le16
*
)
calib_sec
.
data
;
u32
duration
=
mvm
->
thermal_throttle
.
params
->
ct_kill_duration
;
vbg
=
le16_to_cpu
(
calib
[
OTP_WP_DTS_VBG
]);
if
(
test_bit
(
IWL_MVM_STATUS_HW_CTKILL
,
&
mvm
->
status
))
return
;
if
(
vbg
<
MEAS_VBG_MIN_VAL
||
vbg
>
MEAS_VBG_MAX_VAL
)
vbg
=
MEAS_VBG_DEFAULT_VAL
;
IWL_ERR
(
mvm
,
"Enter CT Kill
\n
"
);
iwl_mvm_set_hw_ctkill_state
(
mvm
,
true
)
;
return
vbg
;
/* Don't schedule an exit work if we're in test mode, since
* the temperature will not change unless we manually set it
* again (or disable testing).
*/
if
(
!
mvm
->
temperature_test
)
schedule_delayed_work
(
&
mvm
->
thermal_throttle
.
ct_kill_exit
,
round_jiffies_relative
(
duration
*
HZ
));
}
static
u16
iwl_mvm_dts_get_ptat_deviation_offset
(
struct
iwl_mvm
*
mvm
)
static
void
iwl_mvm_exit_ctkill
(
struct
iwl_mvm
*
mvm
)
{
const
u8
*
calib
;
u8
ptat
,
pa1
,
pa2
,
median
;
/* TODO: move parsing to NVM code */
calib
=
mvm
->
nvm_sections
[
NVM_SECTION_TYPE_CALIBRATION
].
data
;
ptat
=
calib
[
OTP_DTS_DIODE_DEVIATION
*
2
];
pa1
=
calib
[
OTP_DTS_DIODE_DEVIATION
*
2
+
1
];
pa2
=
calib
[
OTP_DTS_DIODE_DEVIATION
*
2
+
2
];
/* get the median: */
if
(
ptat
>
pa1
)
{
if
(
ptat
>
pa2
)
median
=
(
pa1
>
pa2
)
?
pa1
:
pa2
;
else
median
=
ptat
;
}
else
{
if
(
pa1
>
pa2
)
median
=
(
ptat
>
pa2
)
?
ptat
:
pa2
;
else
median
=
pa1
;
}
if
(
!
test_bit
(
IWL_MVM_STATUS_HW_CTKILL
,
&
mvm
->
status
))
return
;
return
ptat
-
median
;
IWL_ERR
(
mvm
,
"Exit CT Kill
\n
"
);
iwl_mvm_set_hw_ctkill_state
(
mvm
,
false
);
}
static
u8
iwl_mvm_dts_calibrate_ptat_deviation
(
struct
iwl_mvm
*
mvm
,
u8
value
)
static
bool
iwl_mvm_temp_notif
(
struct
iwl_notif_wait_data
*
notif_wait
,
struct
iwl_rx_packet
*
pkt
,
void
*
data
)
{
/* Calibrate the PTAT digital value, based on PTAT deviation data: */
s16
new_val
=
value
-
iwl_mvm_dts_get_ptat_deviation_offset
(
mvm
);
struct
iwl_mvm
*
mvm
=
container_of
(
notif_wait
,
struct
iwl_mvm
,
notif_wait
);
int
*
temp
=
data
;
struct
iwl_dts_measurement_notif
*
notif
;
int
len
=
iwl_rx_packet_payload_len
(
pkt
);
if
(
WARN_ON_ONCE
(
len
!=
sizeof
(
*
notif
)))
{
IWL_ERR
(
mvm
,
"Invalid DTS_MEASUREMENT_NOTIFICATION
\n
"
);
return
true
;
}
if
(
new_val
>
PTAT_DIGITAL_VALUE_MAX_VALUE
)
new_val
=
PTAT_DIGITAL_VALUE_MAX_VALUE
;
else
if
(
new_val
<
PTAT_DIGITAL_VALUE_MIN_VALUE
)
new_val
=
PTAT_DIGITAL_VALUE_MIN_VALUE
;
notif
=
(
void
*
)
pkt
->
data
;
return
new_val
;
}
*
temp
=
le32_to_cpu
(
notif
->
temp
);
static
bool
dts_get_adjacent_vrefs
(
struct
iwl_mvm
*
mvm
,
union
dts_diode_results
*
avg_ptat
)
{
u8
vrefs_results
[
DTS_VREFS_NUM
];
u8
low_vref_index
=
0
,
flags
;
u32
reg
;
reg
=
iwl_read_prph
(
mvm
->
trans
,
DTSC_VREF_AVG
);
memcpy
(
vrefs_results
,
&
reg
,
sizeof
(
reg
));
reg
=
iwl_read_prph
(
mvm
->
trans
,
DTSC_VREF5_AVG
);
vrefs_results
[
4
]
=
reg
&
0xff
;
if
(
avg_ptat
->
bits
.
digital_value
<
vrefs_results
[
0
]
||
avg_ptat
->
bits
.
digital_value
>
vrefs_results
[
4
])
return
false
;
if
(
avg_ptat
->
bits
.
digital_value
>
vrefs_results
[
3
])
low_vref_index
=
3
;
else
if
(
avg_ptat
->
bits
.
digital_value
>
vrefs_results
[
2
])
low_vref_index
=
2
;
else
if
(
avg_ptat
->
bits
.
digital_value
>
vrefs_results
[
1
])
low_vref_index
=
1
;
avg_ptat
->
bits
.
vref_low
=
vrefs_results
[
low_vref_index
];
avg_ptat
->
bits
.
vref_high
=
vrefs_results
[
low_vref_index
+
1
];
flags
=
avg_ptat
->
bits
.
flags
;
avg_ptat
->
bits
.
flags
=
(
flags
&
~
DTS_DIODE_REG_FLAGS_VREFS_ID
)
|
(
low_vref_index
&
DTS_DIODE_REG_FLAGS_VREFS_ID
);
return
true
;
}
/* shouldn't be negative, but since it's s32, make sure it isn't */
if
(
WARN_ON_ONCE
(
*
temp
<
0
))
*
temp
=
0
;
/*
* return true it the results are valid, and false otherwise.
*/
static
bool
dts_read_ptat_avg_results
(
struct
iwl_mvm
*
mvm
,
union
dts_diode_results
*
avg_ptat
)
{
u32
reg
;
u8
tmp
;
/* fill the diode value and pass_once with avg-reg results */
reg
=
iwl_read_prph
(
mvm
->
trans
,
DTSC_PTAT_AVG
);
reg
&=
DTS_DIODE_REG_DIG_VAL
|
DTS_DIODE_REG_PASS_ONCE
;
avg_ptat
->
reg_value
=
reg
;
/* calibrate the PTAT digital value */
tmp
=
avg_ptat
->
bits
.
digital_value
;
tmp
=
iwl_mvm_dts_calibrate_ptat_deviation
(
mvm
,
tmp
);
avg_ptat
->
bits
.
digital_value
=
tmp
;
/*
* fill vrefs fields, based on the avgVrefs results
* and the diode value
*/
return
dts_get_adjacent_vrefs
(
mvm
,
avg_ptat
)
&&
DTS_DIODE_VALID
(
avg_ptat
->
bits
.
flags
);
IWL_DEBUG_TEMP
(
mvm
,
"DTS_MEASUREMENT_NOTIFICATION - %d
\n
"
,
*
temp
);
return
true
;
}
static
s32
calculate_nic_temperature
(
union
dts_diode_results
avg_ptat
,
u16
volt_band_gap
)
static
int
iwl_mvm_get_temp_cmd
(
struct
iwl_mvm
*
mvm
)
{
u32
tmp_result
;
u8
vrefs_diff
;
/*
* For temperature calculation (at the end, shift right by 23)
* LUT[(D2-D1)] = ROUND{ 2^23 / ((D2-D1)*9*10) }
* (D2-D1) == 43 44 45 46 47 48 49 50 51
*/
static
const
u16
calc_lut
[
CALC_LUT_SIZE
]
=
{
2168
,
2118
,
2071
,
2026
,
1983
,
1942
,
1902
,
1864
,
1828
,
struct
iwl_dts_measurement_cmd
cmd
=
{
.
flags
=
cpu_to_le32
(
DTS_TRIGGER_CMD_FLAGS_TEMP
),
};
/*
* The diff between the high and low voltage-references is assumed
* to be strictly be in range of [60,68]
*/
vrefs_diff
=
avg_ptat
.
bits
.
vref_high
-
avg_ptat
.
bits
.
vref_low
;
if
(
vrefs_diff
<
CALC_VREFS_MIN_DIFF
||
vrefs_diff
>
CALC_VREFS_MAX_DIFF
)
return
TEMPERATURE_ERROR
;
/* calculate the result: */
tmp_result
=
vrefs_diff
*
(
DTS_DIODE_GET_VREFS_ID
(
avg_ptat
.
bits
.
flags
)
+
9
);
tmp_result
+=
avg_ptat
.
bits
.
digital_value
;
tmp_result
-=
avg_ptat
.
bits
.
vref_high
;
/* multiply by the LUT value (based on the diff) */
tmp_result
*=
calc_lut
[
vrefs_diff
-
CALC_LUT_INDEX_OFFSET
];
/*
* Get the BandGap (the voltage refereces source) error data
* (temperature offset)
*/
tmp_result
*=
volt_band_gap
;
/*
* here, tmp_result value can be up to 32-bits. We want to right-shift
* it *without* sign-extend.
*/
tmp_result
=
tmp_result
>>
CALC_TEMPERATURE_RESULT_SHIFT_OFFSET
;
/*
* at this point, tmp_result should be in the range:
* 200 <= tmp_result <= 365
*/
return
(
s16
)
tmp_result
-
240
;
}
static
s32
check_nic_temperature
(
struct
iwl_mvm
*
mvm
)
{
u16
volt_band_gap
;
union
dts_diode_results
avg_ptat
;
volt_band_gap
=
iwl_mvm_dts_get_volt_band_gap
(
mvm
);
/* disable DTS */
iwl_write_prph
(
mvm
->
trans
,
SHR_MISC_WFM_DTS_EN
,
0
);
/* SV initialization */
iwl_write_prph
(
mvm
->
trans
,
SHR_MISC_WFM_DTS_EN
,
1
);
iwl_write_prph
(
mvm
->
trans
,
DTSC_CFG_MODE
,
DTSC_CFG_MODE_PERIODIC
);
/* wait for results */
msleep
(
100
);
if
(
!
dts_read_ptat_avg_results
(
mvm
,
&
avg_ptat
))
return
TEMPERATURE_ERROR
;
/* disable DTS */
iwl_write_prph
(
mvm
->
trans
,
SHR_MISC_WFM_DTS_EN
,
0
);
return
calculate_nic_temperature
(
avg_ptat
,
volt_band_gap
);
return
iwl_mvm_send_cmd_pdu
(
mvm
,
CMD_DTS_MEASUREMENT_TRIGGER
,
0
,
sizeof
(
cmd
),
&
cmd
);
}
static
void
iwl_mvm_enter_ctkill
(
struct
iwl_mvm
*
mvm
)
static
int
iwl_mvm_get_temp
(
struct
iwl_mvm
*
mvm
)
{
u32
duration
=
mvm
->
thermal_throttle
.
params
->
ct_kill_duration
;
struct
iwl_notification_wait
wait_temp_notif
;
static
const
u8
temp_notif
[]
=
{
DTS_MEASUREMENT_NOTIFICATION
};
int
ret
,
temp
;
if
(
test_bit
(
IWL_MVM_STATUS_HW_CTKILL
,
&
mvm
->
status
))
return
;
lockdep_assert_held
(
&
mvm
->
mutex
);
IWL_ERR
(
mvm
,
"Enter CT Kill
\n
"
);
iwl_mvm_set_hw_ctkill_state
(
mvm
,
true
);
iwl_init_notification_wait
(
&
mvm
->
notif_wait
,
&
wait_temp_notif
,
temp_notif
,
ARRAY_SIZE
(
temp_notif
),
iwl_mvm_temp_notif
,
&
temp
);
/* Don't schedule an exit work if we're in test mode, since
* the temperature will not change unless we manually set it
* again (or disable testing).
*/
if
(
!
mvm
->
temperature_test
)
schedule_delayed_work
(
&
mvm
->
thermal_throttle
.
ct_kill_exit
,
round_jiffies_relative
(
duration
*
HZ
));
}
ret
=
iwl_mvm_get_temp_cmd
(
mvm
);
if
(
ret
)
{
IWL_ERR
(
mvm
,
"Failed to get the temperature (err=%d)
\n
"
,
ret
);
iwl_remove_notification
(
&
mvm
->
notif_wait
,
&
wait_temp_notif
);
return
ret
;
}
static
void
iwl_mvm_exit_ctkill
(
struct
iwl_mvm
*
mvm
)
{
if
(
!
test_bit
(
IWL_MVM_STATUS_HW_CTKILL
,
&
mvm
->
status
))
return
;
ret
=
iwl_wait_notification
(
&
mvm
->
notif_wait
,
&
wait_temp_notif
,
IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT
);
if
(
ret
)
{
IWL_ERR
(
mvm
,
"Getting the temperature timed out
\n
"
);
return
ret
;
}
IWL_ERR
(
mvm
,
"Exit CT Kill
\n
"
);
iwl_mvm_set_hw_ctkill_state
(
mvm
,
false
);
return
temp
;
}
static
void
check_exit_ctkill
(
struct
work_struct
*
work
)
...
...
@@ -352,28 +176,36 @@ static void check_exit_ctkill(struct work_struct *work)
duration
=
tt
->
params
->
ct_kill_duration
;
mutex_lock
(
&
mvm
->
mutex
);
if
(
__iwl_mvm_mac_start
(
mvm
))
goto
reschedule
;
/* make sure the device is available for direct read/writes */
if
(
iwl_mvm_ref_sync
(
mvm
,
IWL_MVM_REF_CHECK_CTKILL
))
if
(
iwl_mvm_ref_sync
(
mvm
,
IWL_MVM_REF_CHECK_CTKILL
))
{
__iwl_mvm_mac_stop
(
mvm
);
goto
reschedule
;
}
iwl_trans_start_hw
(
mvm
->
trans
);
temp
=
check_nic_temperature
(
mvm
);
iwl_trans_stop_device
(
mvm
->
trans
);
temp
=
iwl_mvm_get_temp
(
mvm
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_CHECK_CTKILL
);
if
(
temp
<
MIN_TEMPERATURE
||
temp
>
MAX_TEMPERATURE
)
{
IWL_DEBUG_TEMP
(
mvm
,
"Failed to measure NIC temperature
\n
"
);
__iwl_mvm_mac_stop
(
mvm
);
if
(
temp
<
0
)
goto
reschedule
;
}
IWL_DEBUG_TEMP
(
mvm
,
"NIC temperature: %d
\n
"
,
temp
);
if
(
temp
<=
tt
->
params
->
ct_kill_exit
)
{
mutex_unlock
(
&
mvm
->
mutex
);
iwl_mvm_exit_ctkill
(
mvm
);
return
;
}
reschedule:
mutex_unlock
(
&
mvm
->
mutex
);
schedule_delayed_work
(
&
mvm
->
thermal_throttle
.
ct_kill_exit
,
round_jiffies
(
duration
*
HZ
));
}
...
...
drivers/net/wireless/iwlwifi/mvm/tx.c
View file @
eb2eacf7
...
...
@@ -170,10 +170,14 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
/*
* for data packets, rate info comes from the table inside the fw. This
* table is controlled by LINK_QUALITY commands
* table is controlled by LINK_QUALITY commands. Exclude ctrl port
* frames like EAPOLs which should be treated as mgmt frames. This
* avoids them being sent initially in high rates which increases the
* chances for completion of the 4-Way handshake.
*/
if
(
ieee80211_is_data
(
fc
)
&&
sta
)
{
if
(
ieee80211_is_data
(
fc
)
&&
sta
&&
!
(
info
->
control
.
flags
&
IEEE80211_TX_CTRL_PORT_CTRL_PROTO
))
{
tx_cmd
->
initial_rate_index
=
0
;
tx_cmd
->
tx_flags
|=
cpu_to_le32
(
TX_CMD_FLG_STA_RATE
);
return
;
...
...
@@ -209,7 +213,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
if
(
info
->
band
==
IEEE80211_BAND_2GHZ
&&
!
iwl_mvm_bt_coex_is_shared_ant_avail
(
mvm
))
rate_flags
=
BIT
(
ANT_A
)
<<
RATE_MCS_ANT_POS
;
rate_flags
=
BIT
(
mvm
->
cfg
->
non_shared_ant
)
<<
RATE_MCS_ANT_POS
;
else
rate_flags
=
BIT
(
mvm
->
mgmt_last_antenna_idx
)
<<
RATE_MCS_ANT_POS
;
...
...
drivers/net/wireless/iwlwifi/pcie/drv.c
View file @
eb2eacf7
...
...
@@ -354,11 +354,17 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{
IWL_PCI_DEVICE
(
0x08B3
,
0x8060
,
iwl3160_2n_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B3
,
0x8062
,
iwl3160_n_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B4
,
0x8270
,
iwl3160_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B4
,
0x8370
,
iwl3160_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B4
,
0x8272
,
iwl3160_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B3
,
0x8470
,
iwl3160_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B3
,
0x8570
,
iwl3160_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B3
,
0x1070
,
iwl3160_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B3
,
0x1170
,
iwl3160_2ac_cfg
)},
/* 3165 Series */
{
IWL_PCI_DEVICE
(
0x3165
,
0x4010
,
iwl3165_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x3165
,
0x4210
,
iwl3165_2ac_cfg
)},
/* 7265 Series */
{
IWL_PCI_DEVICE
(
0x095A
,
0x5010
,
iwl7265_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x095A
,
0x5110
,
iwl7265_2ac_cfg
)},
...
...
@@ -380,6 +386,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{
IWL_PCI_DEVICE
(
0x095B
,
0x5202
,
iwl7265_n_cfg
)},
{
IWL_PCI_DEVICE
(
0x095A
,
0x9010
,
iwl7265_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x095A
,
0x9012
,
iwl7265_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x095A
,
0x900A
,
iwl7265_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x095A
,
0x9110
,
iwl7265_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x095A
,
0x9112
,
iwl7265_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x095A
,
0x9210
,
iwl7265_2ac_cfg
)},
...
...
@@ -398,6 +405,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
/* 8000 Series */
{
IWL_PCI_DEVICE
(
0x24F3
,
0x0010
,
iwl8260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x24F3
,
0x0004
,
iwl8260_2n_cfg
)},
{
IWL_PCI_DEVICE
(
0x24F4
,
0x0030
,
iwl8260_2ac_cfg
)},
#endif
/* CONFIG_IWLMVM */
...
...
drivers/net/wireless/iwlwifi/pcie/internal.h
View file @
eb2eacf7
...
...
@@ -257,6 +257,7 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
* @cmd_queue - command queue number
* @rx_buf_size_8k: 8 kB RX buffer size
* @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
* @scd_set_active: should the transport configure the SCD for HCMD queue
* @rx_page_order: page order for receive buffer size
* @wd_timeout: queue watchdog timeout (jiffies)
* @reg_lock: protect hw register access
...
...
@@ -306,6 +307,7 @@ struct iwl_trans_pcie {
bool
rx_buf_size_8k
;
bool
bc_table_dword
;
bool
scd_set_active
;
u32
rx_page_order
;
const
char
*
const
*
command_names
;
...
...
drivers/net/wireless/iwlwifi/pcie/rx.c
View file @
eb2eacf7
...
...
@@ -640,7 +640,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
err
=
iwl_op_mode_rx
(
trans
->
op_mode
,
&
rxcb
,
cmd
);
if
(
reclaim
)
{
kfree
(
txq
->
entries
[
cmd_index
].
free_buf
);
k
z
free
(
txq
->
entries
[
cmd_index
].
free_buf
);
txq
->
entries
[
cmd_index
].
free_buf
=
NULL
;
}
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
View file @
eb2eacf7
...
...
@@ -1171,6 +1171,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
trans_pcie
->
command_names
=
trans_cfg
->
command_names
;
trans_pcie
->
bc_table_dword
=
trans_cfg
->
bc_table_dword
;
trans_pcie
->
scd_set_active
=
trans_cfg
->
scd_set_active
;
/* Initialize NAPI here - it should be before registering to mac80211
* in the opmode but after the HW struct is allocated.
...
...
@@ -2189,7 +2190,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
*/
if
(
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_8000
)
trans
->
hw_rev
=
(
trans
->
hw_rev
&
0xfff0
)
|
(
(
trans
->
hw_rev
<<
2
)
&
0xc
);
(
CSR_HW_REV_STEP
(
trans
->
hw_rev
<<
2
)
);
trans
->
hw_id
=
(
pdev
->
device
<<
16
)
+
pdev
->
subsystem_device
;
snprintf
(
trans
->
hw_id_str
,
sizeof
(
trans
->
hw_id_str
),
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
View file @
eb2eacf7
...
...
@@ -620,8 +620,8 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
/* De-alloc array of command/tx buffers */
if
(
txq_id
==
trans_pcie
->
cmd_queue
)
for
(
i
=
0
;
i
<
txq
->
q
.
n_window
;
i
++
)
{
kfree
(
txq
->
entries
[
i
].
cmd
);
kfree
(
txq
->
entries
[
i
].
free_buf
);
k
z
free
(
txq
->
entries
[
i
].
cmd
);
k
z
free
(
txq
->
entries
[
i
].
free_buf
);
}
/* De-alloc circular buffer of TFDs */
...
...
@@ -1080,7 +1080,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
fifo
=
cfg
->
fifo
;
/* Disable the scheduler prior configuring the cmd queue */
if
(
txq_id
==
trans_pcie
->
cmd_queue
)
if
(
txq_id
==
trans_pcie
->
cmd_queue
&&
trans_pcie
->
scd_set_active
)
iwl_scd_enable_set_active
(
trans
,
0
);
/* Stop this Tx queue before configuring it */
...
...
@@ -1142,7 +1143,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
SCD_QUEUE_STTS_REG_MSK
);
/* enable the scheduler for this queue (only) */
if
(
txq_id
==
trans_pcie
->
cmd_queue
)
if
(
txq_id
==
trans_pcie
->
cmd_queue
&&
trans_pcie
->
scd_set_active
)
iwl_scd_enable_set_active
(
trans
,
BIT
(
txq_id
));
}
...
...
@@ -1407,7 +1409,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
out_meta
->
flags
=
cmd
->
flags
;
if
(
WARN_ON_ONCE
(
txq
->
entries
[
idx
].
free_buf
))
kfree
(
txq
->
entries
[
idx
].
free_buf
);
k
z
free
(
txq
->
entries
[
idx
].
free_buf
);
txq
->
entries
[
idx
].
free_buf
=
dup_buf
;
trace_iwlwifi_dev_hcmd
(
trans
->
dev
,
cmd
,
cmd_size
,
&
out_cmd
->
hdr
);
...
...
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