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
5f4ef719
Commit
5f4ef719
authored
Jun 25, 2014
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
parents
855df36d
c47af22a
Changes
31
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
609 additions
and
177 deletions
+609
-177
drivers/net/wireless/iwlwifi/dvm/power.c
drivers/net/wireless/iwlwifi/dvm/power.c
+9
-0
drivers/net/wireless/iwlwifi/iwl-8000.c
drivers/net/wireless/iwlwifi/iwl-8000.c
+2
-3
drivers/net/wireless/iwlwifi/iwl-config.h
drivers/net/wireless/iwlwifi/iwl-config.h
+1
-1
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-drv.c
+15
-0
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+0
-1
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+44
-2
drivers/net/wireless/iwlwifi/iwl-fw-file.h
drivers/net/wireless/iwlwifi/iwl-fw-file.h
+4
-2
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/iwl-fw.h
+8
-0
drivers/net/wireless/iwlwifi/iwl-modparams.h
drivers/net/wireless/iwlwifi/iwl-modparams.h
+2
-0
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+40
-16
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl-prph.h
+6
-0
drivers/net/wireless/iwlwifi/mvm/coex.c
drivers/net/wireless/iwlwifi/mvm/coex.c
+64
-13
drivers/net/wireless/iwlwifi/mvm/constants.h
drivers/net/wireless/iwlwifi/mvm/constants.h
+2
-0
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
+39
-0
drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
+9
-1
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+1
-1
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+14
-33
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+2
-5
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+14
-0
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+29
-16
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+14
-1
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+14
-0
drivers/net/wireless/iwlwifi/mvm/nvm.c
drivers/net/wireless/iwlwifi/mvm/nvm.c
+25
-4
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/ops.c
+25
-6
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/scan.c
+50
-65
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.c
+20
-0
drivers/net/wireless/iwlwifi/mvm/sta.h
drivers/net/wireless/iwlwifi/mvm/sta.h
+2
-0
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+7
-1
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/internal.h
+7
-0
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+139
-6
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+1
-0
No files found.
drivers/net/wireless/iwlwifi/dvm/power.c
View file @
5f4ef719
...
...
@@ -40,6 +40,10 @@
#include "commands.h"
#include "power.h"
static
bool
force_cam
;
module_param
(
force_cam
,
bool
,
0644
);
MODULE_PARM_DESC
(
force_cam
,
"force continuously aware mode (no power saving at all)"
);
/*
* Setting power level allows the card to go to sleep when not busy.
*
...
...
@@ -288,6 +292,11 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
bool
enabled
=
priv
->
hw
->
conf
.
flags
&
IEEE80211_CONF_PS
;
int
dtimper
;
if
(
force_cam
)
{
iwl_power_sleep_cam_cmd
(
priv
,
cmd
);
return
;
}
dtimper
=
priv
->
hw
->
conf
.
ps_dtim_period
?:
1
;
if
(
priv
->
wowlan
)
...
...
drivers/net/wireless/iwlwifi/iwl-8000.c
View file @
5f4ef719
...
...
@@ -67,7 +67,7 @@
#include "iwl-agn-hw.h"
/* Highest firmware API version supported */
#define IWL8000_UCODE_API_MAX
8
#define IWL8000_UCODE_API_MAX
9
/* Oldest version we won't warn about */
#define IWL8000_UCODE_API_OK 8
...
...
@@ -119,10 +119,9 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
.
ht_params
=
&
iwl8000_ht_params
,
.
nvm_ver
=
IWL8000_NVM_VERSION
,
.
nvm_calib_ver
=
IWL8000_TX_POWER_VERSION
,
.
default_nvm_file
=
DEFAULT_NVM_FILE_FAMILY_8000
,
};
const
struct
iwl_cfg
iwl8260_
n
_cfg
=
{
const
struct
iwl_cfg
iwl8260_
2ac_sdio
_cfg
=
{
.
name
=
"Intel(R) Dual Band Wireless-AC 8260"
,
.
fw_name_pre
=
IWL8000_FW_PRE
,
IWL_DEVICE_8000
,
...
...
drivers/net/wireless/iwlwifi/iwl-config.h
View file @
5f4ef719
...
...
@@ -337,7 +337,7 @@ 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_2ac_cfg
;
extern
const
struct
iwl_cfg
iwl8260_
n
_cfg
;
extern
const
struct
iwl_cfg
iwl8260_
2ac_sdio
_cfg
;
#endif
/* CONFIG_IWLMVM */
#endif
/* __IWL_CONFIG_H__ */
drivers/net/wireless/iwlwifi/iwl-drv.c
View file @
5f4ef719
...
...
@@ -155,6 +155,8 @@ static struct iwlwifi_opmode_table {
[
MVM_OP_MODE
]
=
{
.
name
=
"iwlmvm"
,
.
ops
=
NULL
},
};
#define IWL_DEFAULT_SCAN_CHANNELS 40
/*
* struct fw_sec: Just for the image parsing proccess.
* For the fw storage we are using struct fw_desc.
...
...
@@ -565,6 +567,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
}
drv
->
fw
.
ucode_ver
=
le32_to_cpu
(
ucode
->
ver
);
memcpy
(
drv
->
fw
.
human_readable
,
ucode
->
human_readable
,
sizeof
(
drv
->
fw
.
human_readable
));
build
=
le32_to_cpu
(
ucode
->
build
);
if
(
build
)
...
...
@@ -819,6 +823,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
if
(
iwl_store_cscheme
(
&
drv
->
fw
,
tlv_data
,
tlv_len
))
goto
invalid_tlv_len
;
break
;
case
IWL_UCODE_TLV_N_SCAN_CHANNELS
:
if
(
tlv_len
!=
sizeof
(
u32
))
goto
invalid_tlv_len
;
capa
->
n_scan_channels
=
le32_to_cpup
((
__le32
*
)
tlv_data
);
break
;
default:
IWL_DEBUG_INFO
(
drv
,
"unknown TLV: %d
\n
"
,
tlv_type
);
break
;
...
...
@@ -973,6 +983,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
fw
->
ucode_capa
.
max_probe_length
=
IWL_DEFAULT_MAX_PROBE_LENGTH
;
fw
->
ucode_capa
.
standard_phy_calibration_size
=
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE
;
fw
->
ucode_capa
.
n_scan_channels
=
IWL_DEFAULT_SCAN_CHANNELS
;
if
(
!
api_ok
)
api_ok
=
api_max
;
...
...
@@ -1394,3 +1405,7 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
int
,
S_IRUGO
);
MODULE_PARM_DESC
(
power_level
,
"default power save level (range from 1 - 5, default: 1)"
);
module_param_named
(
fw_monitor
,
iwlwifi_mod_params
.
fw_monitor
,
bool
,
S_IRUGO
);
MODULE_PARM_DESC
(
dbgm
,
"firmware monitor - to debug FW (default: false - needs lots of memory)"
);
drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
View file @
5f4ef719
...
...
@@ -779,7 +779,6 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
if
(
cfg
->
ht_params
->
ht40_bands
&
BIT
(
band
))
{
ht_info
->
cap
|=
IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
ht_info
->
cap
|=
IEEE80211_HT_CAP_SGI_40
;
ht_info
->
mcs
.
rx_mask
[
4
]
=
0x01
;
max_bit_rate
=
MAX_BIT_RATE_40_MHZ
;
}
...
...
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
View file @
5f4ef719
...
...
@@ -74,12 +74,17 @@
* @IWL_FW_ERROR_DUMP_RXF:
* @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
* &struct iwl_fw_error_dump_txcmd packets
* @IWL_FW_ERROR_DUMP_DEV_FW_INFO: struct %iwl_fw_error_dump_info
* info on the device / firmware.
* @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor
*/
enum
iwl_fw_error_dump_type
{
IWL_FW_ERROR_DUMP_SRAM
=
0
,
IWL_FW_ERROR_DUMP_REG
=
1
,
IWL_FW_ERROR_DUMP_RXF
=
2
,
IWL_FW_ERROR_DUMP_TXCMD
=
3
,
IWL_FW_ERROR_DUMP_DEV_FW_INFO
=
4
,
IWL_FW_ERROR_DUMP_FW_MONITOR
=
5
,
IWL_FW_ERROR_DUMP_MAX
,
};
...
...
@@ -120,13 +125,50 @@ struct iwl_fw_error_dump_txcmd {
u8
data
[];
}
__packed
;
enum
iwl_fw_error_dump_family
{
IWL_FW_ERROR_DUMP_FAMILY_7
=
7
,
IWL_FW_ERROR_DUMP_FAMILY_8
=
8
,
};
/**
* struct iwl_fw_error_dump_info - info on the device / firmware
* @device_family: the family of the device (7 / 8)
* @hw_step: the step of the device
* @fw_human_readable: human readable FW version
* @dev_human_readable: name of the device
* @bus_human_readable: name of the bus used
*/
struct
iwl_fw_error_dump_info
{
__le32
device_family
;
__le32
hw_step
;
u8
fw_human_readable
[
FW_VER_HUMAN_READABLE_SZ
];
u8
dev_human_readable
[
64
];
u8
bus_human_readable
[
8
];
}
__packed
;
/**
* struct iwl_fw_error_fw_mon - FW monitor data
* @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer
* @fw_mon_base_ptr: base pointer of the data
* @fw_mon_cycle_cnt: number of wrap arounds
* @reserved: for future use
* @data: captured data
*/
struct
iwl_fw_error_fw_mon
{
__le32
fw_mon_wr_ptr
;
__le32
fw_mon_base_ptr
;
__le32
fw_mon_cycle_cnt
;
__le32
reserved
[
3
];
u8
data
[];
}
__packed
;
/**
* iwl_
mvm_
fw_error_next_data - advance fw error dump data pointer
* iwl_fw_error_next_data - advance fw error dump data pointer
* @data: previous data block
* Returns: next data block
*/
static
inline
struct
iwl_fw_error_dump_data
*
iwl_
mvm_
fw_error_next_data
(
struct
iwl_fw_error_dump_data
*
data
)
iwl_fw_error_next_data
(
struct
iwl_fw_error_dump_data
*
data
)
{
return
(
void
*
)(
data
->
data
+
le32_to_cpu
(
data
->
len
));
}
...
...
drivers/net/wireless/iwlwifi/iwl-fw-file.h
View file @
5f4ef719
...
...
@@ -128,6 +128,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_CSCHEME
=
28
,
IWL_UCODE_TLV_API_CHANGES_SET
=
29
,
IWL_UCODE_TLV_ENABLED_CAPABILITIES
=
30
,
IWL_UCODE_TLV_N_SCAN_CHANNELS
=
31
,
};
struct
iwl_ucode_tlv
{
...
...
@@ -137,6 +138,7 @@ struct iwl_ucode_tlv {
};
#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
#define FW_VER_HUMAN_READABLE_SZ 64
struct
iwl_tlv_ucode_header
{
/*
...
...
@@ -147,7 +149,7 @@ struct iwl_tlv_ucode_header {
*/
__le32
zero
;
__le32
magic
;
u8
human_readable
[
64
];
u8
human_readable
[
FW_VER_HUMAN_READABLE_SZ
];
__le32
ver
;
/* major/minor/API/serial */
__le32
build
;
__le64
ignore
;
...
...
drivers/net/wireless/iwlwifi/iwl-fw.h
View file @
5f4ef719
...
...
@@ -65,6 +65,8 @@
#include <linux/types.h>
#include <net/mac80211.h>
#include "iwl-fw-file.h"
/**
* enum iwl_ucode_tlv_flag - ucode API flags
* @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
...
...
@@ -117,11 +119,15 @@ enum iwl_ucode_tlv_flag {
/**
* enum iwl_ucode_tlv_api - ucode api
* @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
* @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
* @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.
*/
enum
iwl_ucode_tlv_api
{
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID
=
BIT
(
0
),
IWL_UCODE_TLV_CAPA_EXTENDED_BEACON
=
BIT
(
1
),
IWL_UCODE_TLV_API_CSA_FLOW
=
BIT
(
4
),
IWL_UCODE_TLV_API_DISABLE_STA_TX
=
BIT
(
5
),
};
/**
...
...
@@ -178,6 +184,7 @@ enum iwl_ucode_sec {
struct
iwl_ucode_capabilities
{
u32
max_probe_length
;
u32
n_scan_channels
;
u32
standard_phy_calibration_size
;
u32
flags
;
u32
api
[
IWL_API_ARRAY_SIZE
];
...
...
@@ -311,6 +318,7 @@ struct iwl_fw {
bool
mvm_fw
;
struct
ieee80211_cipher_scheme
cs
[
IWL_UCODE_MAX_CS
];
u8
human_readable
[
FW_VER_HUMAN_READABLE_SZ
];
};
#endif
/* __iwl_fw_h__ */
drivers/net/wireless/iwlwifi/iwl-modparams.h
View file @
5f4ef719
...
...
@@ -103,6 +103,7 @@ enum iwl_disable_11n {
* @power_level: power level, default = 1
* @debug_level: levels are IWL_DL_*
* @ant_coupling: antenna coupling in dB, default = 0
* @fw_monitor: allow to use firmware monitor
*/
struct
iwl_mod_params
{
int
sw_crypto
;
...
...
@@ -120,6 +121,7 @@ struct iwl_mod_params {
int
ant_coupling
;
char
*
nvm_file
;
bool
uapsd_disable
;
bool
fw_monitor
;
};
#endif
/* #__iwl_modparams_h__ */
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
View file @
5f4ef719
...
...
@@ -174,7 +174,9 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
* @NVM_CHANNEL_IBSS: usable as an IBSS channel
* @NVM_CHANNEL_ACTIVE: active scanning allowed
* @NVM_CHANNEL_RADAR: radar detection required
* @NVM_CHANNEL_DFS: dynamic freq selection candidate
* @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
* @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
* on same channel on 2.4 or same UNII band on 5.2
* @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
...
...
@@ -185,7 +187,8 @@ enum iwl_nvm_channel_flags {
NVM_CHANNEL_IBSS
=
BIT
(
1
),
NVM_CHANNEL_ACTIVE
=
BIT
(
3
),
NVM_CHANNEL_RADAR
=
BIT
(
4
),
NVM_CHANNEL_DFS
=
BIT
(
7
),
NVM_CHANNEL_INDOOR_ONLY
=
BIT
(
5
),
NVM_CHANNEL_GO_CONCURRENT
=
BIT
(
6
),
NVM_CHANNEL_WIDE
=
BIT
(
8
),
NVM_CHANNEL_40MHZ
=
BIT
(
9
),
NVM_CHANNEL_80MHZ
=
BIT
(
10
),
...
...
@@ -273,6 +276,16 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
if
(
ch_flags
&
NVM_CHANNEL_RADAR
)
channel
->
flags
|=
IEEE80211_CHAN_RADAR
;
if
(
ch_flags
&
NVM_CHANNEL_INDOOR_ONLY
)
channel
->
flags
|=
IEEE80211_CHAN_INDOOR_ONLY
;
/* Set the GO concurrent flag only in case that NO_IR is set.
* Otherwise it is meaningless
*/
if
((
ch_flags
&
NVM_CHANNEL_GO_CONCURRENT
)
&&
(
channel
->
flags
&
IEEE80211_CHAN_NO_IR
))
channel
->
flags
|=
IEEE80211_CHAN_GO_CONCURRENT
;
/* Initialize regulatory-based run-time data */
/*
...
...
@@ -282,7 +295,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
channel
->
max_power
=
DEFAULT_MAX_TX_POWER
;
is_5ghz
=
channel
->
band
==
IEEE80211_BAND_5GHZ
;
IWL_DEBUG_EEPROM
(
dev
,
"Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported
\n
"
,
"Ch. %d [%sGHz] %s%s%s%s%s%s
%s
(0x%02x %ddBm): Ad-Hoc %ssupported
\n
"
,
channel
->
hw_value
,
is_5ghz
?
"5.2"
:
"2.4"
,
CHECK_AND_PRINT_I
(
VALID
),
...
...
@@ -290,7 +303,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
CHECK_AND_PRINT_I
(
ACTIVE
),
CHECK_AND_PRINT_I
(
RADAR
),
CHECK_AND_PRINT_I
(
WIDE
),
CHECK_AND_PRINT_I
(
DFS
),
CHECK_AND_PRINT_I
(
INDOOR_ONLY
),
CHECK_AND_PRINT_I
(
GO_CONCURRENT
),
ch_flags
,
channel
->
max_power
,
((
ch_flags
&
NVM_CHANNEL_IBSS
)
&&
...
...
@@ -462,7 +476,8 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
data
->
hw_addr
[
5
]
=
hw_addr
[
4
];
}
static
void
iwl_set_hw_address_family_8000
(
const
struct
iwl_cfg
*
cfg
,
static
void
iwl_set_hw_address_family_8000
(
struct
device
*
dev
,
const
struct
iwl_cfg
*
cfg
,
struct
iwl_nvm_data
*
data
,
const
__le16
*
mac_override
,
const
__le16
*
nvm_hw
)
...
...
@@ -481,10 +496,14 @@ static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
data
->
hw_addr
[
4
]
=
hw_addr
[
5
];
data
->
hw_addr
[
5
]
=
hw_addr
[
4
];
if
(
is_valid_ether_addr
(
hw_addr
))
if
(
is_valid_ether_addr
(
data
->
hw_addr
))
return
;
IWL_ERR_DEV
(
dev
,
"mac address from nvm override section is not valid
\n
"
);
}
if
(
nvm_hw
)
{
/* take the MAC address from the OTP */
hw_addr
=
(
const
u8
*
)(
nvm_hw
+
HW_ADDR0_FAMILY_8000
);
data
->
hw_addr
[
0
]
=
hw_addr
[
3
];
...
...
@@ -495,6 +514,10 @@ static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
hw_addr
=
(
const
u8
*
)(
nvm_hw
+
HW_ADDR1_FAMILY_8000
);
data
->
hw_addr
[
4
]
=
hw_addr
[
1
];
data
->
hw_addr
[
5
]
=
hw_addr
[
0
];
return
;
}
IWL_ERR_DEV
(
dev
,
"mac address is not found
\n
"
);
}
struct
iwl_nvm_data
*
...
...
@@ -556,7 +579,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
rx_chains
);
}
else
{
/* MAC address in family 8000 */
iwl_set_hw_address_family_8000
(
cfg
,
data
,
mac_override
,
nvm_hw
);
iwl_set_hw_address_family_8000
(
dev
,
cfg
,
data
,
mac_override
,
nvm_hw
);
iwl_init_sbands
(
dev
,
cfg
,
data
,
regulatory
,
sku
&
NVM_SKU_CAP_11AC_ENABLE
,
tx_chains
,
...
...
drivers/net/wireless/iwlwifi/iwl-prph.h
View file @
5f4ef719
...
...
@@ -359,4 +359,10 @@ enum secure_load_status_reg {
#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
/* FW monitor */
#define MON_BUFF_BASE_ADDR (0xa03c3c)
#define MON_BUFF_END_ADDR (0xa03c40)
#define MON_BUFF_WRPTR (0xa03c44)
#define MON_BUFF_CYCLE_CNT (0xa03c48)
#endif
/* __iwl_prph_h__ */
drivers/net/wireless/iwlwifi/mvm/coex.c
View file @
5f4ef719
...
...
@@ -100,12 +100,13 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
#undef EVENT_PRIO_ANT
#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
#define BT_ANTENNA_COUPLING_THRESHOLD (30)
static
int
iwl_send_bt_prio_tbl
(
struct
iwl_mvm
*
mvm
)
{
if
(
unlikely
(
mvm
->
bt_force_ant_mode
!=
BT_FORCE_ANT_DIS
))
return
0
;
return
iwl_mvm_send_cmd_pdu
(
mvm
,
BT_COEX_PRIO_TABLE
,
0
,
sizeof
(
struct
iwl_bt_coex_prio_tbl_cmd
),
&
iwl_bt_prio_tbl
);
...
...
@@ -535,7 +536,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
if
(
!
chanctx_conf
||
chanctx_conf
->
def
.
chan
->
band
!=
IEEE80211_BAND_2GHZ
)
{
rcu_read_unlock
();
return
BT_COEX_
LOOSE
_LUT
;
return
BT_COEX_
INVALID
_LUT
;
}
ret
=
BT_COEX_TX_DIS_LUT
;
...
...
@@ -578,6 +579,29 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
return
-
ENOMEM
;
cmd
.
data
[
0
]
=
bt_cmd
;
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
unlikely
(
mvm
->
bt_force_ant_mode
!=
BT_FORCE_ANT_DIS
))
{
switch
(
mvm
->
bt_force_ant_mode
)
{
case
BT_FORCE_ANT_AUTO
:
flags
=
BT_COEX_AUTO
;
break
;
case
BT_FORCE_ANT_BT
:
flags
=
BT_COEX_BT
;
break
;
case
BT_FORCE_ANT_WIFI
:
flags
=
BT_COEX_WIFI
;
break
;
default:
WARN_ON
(
1
);
flags
=
0
;
}
bt_cmd
->
flags
=
cpu_to_le32
(
flags
);
bt_cmd
->
valid_bit_msk
=
cpu_to_le32
(
BT_VALID_ENABLE
);
goto
send_cmd
;
}
bt_cmd
->
max_kill
=
5
;
bt_cmd
->
bt4_antenna_isolation_thr
=
BT_ANTENNA_COUPLING_THRESHOLD
;
bt_cmd
->
bt4_antenna_isolation
=
iwlwifi_mod_params
.
ant_coupling
;
...
...
@@ -642,6 +666,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
bt_cmd
->
kill_cts_msk
=
cpu_to_le32
(
iwl_bt_cts_kill_msk
[
BT_KILL_MSK_DEFAULT
]);
send_cmd:
memset
(
&
mvm
->
last_bt_notif
,
0
,
sizeof
(
mvm
->
last_bt_notif
));
memset
(
&
mvm
->
last_bt_ci_cmd
,
0
,
sizeof
(
mvm
->
last_bt_ci_cmd
));
...
...
@@ -780,9 +805,9 @@ void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm,
mvmvif
->
bf_data
.
last_bt_coex_event
=
rssi
;
mvmvif
->
bf_data
.
bt_coex_max_thold
=
enable
?
BT_ENABLE_REDUCED_TXPOWER_THRESHOLD
:
0
;
enable
?
-
IWL_MVM_BT_COEX_EN_RED_TXP_THRESH
:
0
;
mvmvif
->
bf_data
.
bt_coex_min_thold
=
enable
?
BT_DISABLE_REDUCED_TXPOWER_THRESHOLD
:
0
;
enable
?
-
IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH
:
0
;
}
/* must be called under rcu_read_lock */
...
...
@@ -919,7 +944,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
/* if the RSSI isn't valid, fake it is very low */
if
(
!
ave_rssi
)
ave_rssi
=
-
100
;
if
(
ave_rssi
>
BT_ENABLE_REDUCED_TXPOWER_THRESHOLD
)
{
if
(
ave_rssi
>
-
IWL_MVM_BT_COEX_EN_RED_TXP_THRESH
)
{
if
(
iwl_mvm_bt_coex_reduced_txp
(
mvm
,
mvmvif
->
ap_sta_id
,
true
))
IWL_ERR
(
mvm
,
"Couldn't send BT_CONFIG cmd
\n
"
);
...
...
@@ -930,7 +955,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
* the iteration, if one interface's rssi isn't good enough,
* bt_kill_msk will be set to default values.
*/
}
else
if
(
ave_rssi
<
BT_DISABLE_REDUCED_TXPOWER_THRESHOLD
)
{
}
else
if
(
ave_rssi
<
-
IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH
)
{
if
(
iwl_mvm_bt_coex_reduced_txp
(
mvm
,
mvmvif
->
ap_sta_id
,
false
))
IWL_ERR
(
mvm
,
"Couldn't send BT_CONFIG cmd
\n
"
);
...
...
@@ -955,6 +980,10 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
struct
iwl_bt_coex_ci_cmd
cmd
=
{};
u8
ci_bw_idx
;
/* Ignore updates if we are in force mode */
if
(
unlikely
(
mvm
->
bt_force_ant_mode
!=
BT_FORCE_ANT_DIS
))
return
;
rcu_read_lock
();
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
...
...
@@ -1121,6 +1150,10 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
lockdep_assert_held
(
&
mvm
->
mutex
);
/* Ignore updates if we are in force mode */
if
(
unlikely
(
mvm
->
bt_force_ant_mode
!=
BT_FORCE_ANT_DIS
))
return
;
/*
* Rssi update while not associated - can happen since the statistics
* are handled asynchronously
...
...
@@ -1177,9 +1210,12 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
BT_HIGH_TRAFFIC
)
return
LINK_QUAL_AGG_TIME_LIMIT_DEF
;
if
(
mvm
->
last_bt_notif
.
ttc_enabled
)
return
LINK_QUAL_AGG_TIME_LIMIT_DEF
;
lut_type
=
iwl_get_coex_type
(
mvm
,
mvmsta
->
vif
);
if
(
lut_type
==
BT_COEX_LOOSE_LUT
)
if
(
lut_type
==
BT_COEX_LOOSE_LUT
||
lut_type
==
BT_COEX_INVALID_LUT
)
return
LINK_QUAL_AGG_TIME_LIMIT_DEF
;
/* tight coex, high bt traffic, reduce AGG time limit */
...
...
@@ -1190,18 +1226,29 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
struct
ieee80211_sta
*
sta
)
{
struct
iwl_mvm_sta
*
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
enum
iwl_bt_coex_lut_type
lut_type
;
if
(
mvm
->
last_bt_notif
.
ttc_enabled
)
return
true
;
if
(
le32_to_cpu
(
mvm
->
last_bt_notif
.
bt_activity_grading
)
<
BT_HIGH_TRAFFIC
)
return
true
;
/*
* In Tight, BT can't Rx while we Tx, so use both antennas since BT is
* already killed.
* In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while we
* Tx.
* In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas
* since BT is already killed.
* In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while
* we Tx.
* When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO.
*/
return
iwl_get_coex_type
(
mvm
,
mvmsta
->
vif
)
==
BT_COEX_TIGHT_LUT
;
lut_type
=
iwl_get_coex_type
(
mvm
,
mvmsta
->
vif
);
return
lut_type
!=
BT_COEX_LOOSE_LUT
;
}
bool
iwl_mvm_bt_coex_is_shared_ant_avail
(
struct
iwl_mvm
*
mvm
)
{
return
le32_to_cpu
(
mvm
->
last_bt_notif
.
bt_activity_grading
)
==
BT_OFF
;
}
bool
iwl_mvm_bt_coex_is_tpc_allowed
(
struct
iwl_mvm
*
mvm
,
...
...
@@ -1274,6 +1321,10 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
lockdep_assert_held
(
&
mvm
->
mutex
);
/* Ignore updates if we are in force mode */
if
(
unlikely
(
mvm
->
bt_force_ant_mode
!=
BT_FORCE_ANT_DIS
))
return
0
;
if
(
ant_isolation
==
mvm
->
last_ant_isol
)
return
0
;
...
...
drivers/net/wireless/iwlwifi/mvm/constants.h
View file @
5f4ef719
...
...
@@ -79,6 +79,8 @@
#define IWL_MVM_PS_SNOOZE_WINDOW 50
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62
#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65
#define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING 1
#define IWL_MVM_BT_COEX_MPLUT 1
...
...
drivers/net/wireless/iwlwifi/mvm/debugfs.c
View file @
5f4ef719
...
...
@@ -455,6 +455,43 @@ iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf,
return
count
;
}
static
ssize_t
iwl_dbgfs_bt_force_ant_write
(
struct
iwl_mvm
*
mvm
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
static
const
char
*
const
modes_str
[
BT_FORCE_ANT_MAX
]
=
{
[
BT_FORCE_ANT_DIS
]
=
"dis"
,
[
BT_FORCE_ANT_AUTO
]
=
"auto"
,
[
BT_FORCE_ANT_BT
]
=
"bt"
,
[
BT_FORCE_ANT_WIFI
]
=
"wifi"
,
};
int
ret
,
bt_force_ant_mode
;
for
(
bt_force_ant_mode
=
0
;
bt_force_ant_mode
<
ARRAY_SIZE
(
modes_str
);
bt_force_ant_mode
++
)
{
if
(
!
strcmp
(
buf
,
modes_str
[
bt_force_ant_mode
]))
break
;
}
if
(
bt_force_ant_mode
>=
ARRAY_SIZE
(
modes_str
))
return
-
EINVAL
;
ret
=
0
;
mutex_lock
(
&
mvm
->
mutex
);
if
(
mvm
->
bt_force_ant_mode
==
bt_force_ant_mode
)
goto
out
;
mvm
->
bt_force_ant_mode
=
bt_force_ant_mode
;
IWL_DEBUG_COEX
(
mvm
,
"Force mode: %s
\n
"
,
modes_str
[
mvm
->
bt_force_ant_mode
]);
ret
=
iwl_send_bt_init_conf
(
mvm
);
out:
mutex_unlock
(
&
mvm
->
mutex
);
return
ret
?:
count
;
}
#define PRINT_STATS_LE32(_str, _val) \
pos += scnprintf(buf + pos, bufsz - pos, \
fmt_table, _str, \
...
...
@@ -1101,6 +1138,7 @@ MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_restart
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_nmi
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
bt_tx_prio
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
bt_force_ant
,
10
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
scan_ant_rxchain
,
8
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
d0i3_refs
,
8
);
...
...
@@ -1142,6 +1180,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE
(
fw_restart
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_nmi
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_tx_prio
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_force_ant
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
scan_ant_rxchain
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
prph_reg
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
View file @
5f4ef719
...
...
@@ -76,6 +76,9 @@
* @BT_COEX_2W:
* @BT_COEX_3W:
* @BT_COEX_NW:
* @BT_COEX_AUTO:
* @BT_COEX_BT: Antenna is for BT (manufacuring tests)
* @BT_COEX_WIFI: Antenna is for BT (manufacuring tests)
* @BT_COEX_SYNC2SCO:
* @BT_COEX_CORUNNING:
* @BT_COEX_MPLUT:
...
...
@@ -89,6 +92,9 @@ enum iwl_bt_coex_flags {
BT_COEX_2W
=
0x1
<<
BT_COEX_MODE_POS
,
BT_COEX_3W
=
0x2
<<
BT_COEX_MODE_POS
,
BT_COEX_NW
=
0x3
<<
BT_COEX_MODE_POS
,
BT_COEX_AUTO
=
0x5
<<
BT_COEX_MODE_POS
,
BT_COEX_BT
=
0x6
<<
BT_COEX_MODE_POS
,
BT_COEX_WIFI
=
0x7
<<
BT_COEX_MODE_POS
,
BT_COEX_SYNC2SCO
=
BIT
(
7
),
BT_COEX_CORUNNING
=
BIT
(
8
),
BT_COEX_MPLUT
=
BIT
(
9
),
...
...
@@ -299,6 +305,7 @@ enum iwl_bt_activity_grading {
* @bt_traffic_load: load of BT traffic
* @bt_agg_traffic_load: aggregated load of BT traffic
* @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
* @ttc_enabled: true if ttc has been enabled by the firmware
* @primary_ch_lut: LUT used for primary channel
* @secondary_ch_lut: LUT used for secondary channel
* @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
...
...
@@ -311,7 +318,8 @@ struct iwl_bt_coex_profile_notif {
u8
bt_traffic_load
;
u8
bt_agg_traffic_load
;
u8
bt_ci_compliance
;
u8
reserved
[
3
];
u8
ttc_enabled
;
__le16
reserved
;
__le32
primary_ch_lut
;
__le32
secondary_ch_lut
;
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
View file @
5f4ef719
...
...
@@ -336,7 +336,7 @@ struct iwl_beacon_filter_cmd {
#define IWL_BF_DEBUG_FLAG_D0I3 0
#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
#define IWL_BF_ESCAPE_TIMER_D0I3
1024
#define IWL_BF_ESCAPE_TIMER_D0I3
0
#define IWL_BF_ESCAPE_TIMER_MAX 1024
#define IWL_BF_ESCAPE_TIMER_MIN 0
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
View file @
5f4ef719
...
...
@@ -169,19 +169,13 @@ enum iwl_scan_type {
SCAN_TYPE_DISCOVERY_FORCED
=
6
,
};
/* SCAN_ACTIVITY_TYPE_E_VER_1 */
/**
* Maximal number of channels to scan
* it should be equal to:
* max(IWL_NUM_CHANNELS, IWL_NUM_CHANNELS_FAMILY_8000)
*/
#define MAX_NUM_SCAN_CHANNELS 50
/**
* struct iwl_scan_cmd - scan request command
* ( SCAN_REQUEST_CMD = 0x80 )
* @len: command length in bytes
* @scan_flags: scan flags from SCAN_FLAGS_*
* @channel_count: num of channels in channel list (1 - MAX_NUM_SCAN_CHANNELS)
* @channel_count: num of channels in channel list
* (1 - ucode_capa.n_scan_channels)
* @quiet_time: in msecs, dwell this time for active scan on quiet channels
* @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
* this number of packets were received (typically 1)
...
...
@@ -345,7 +339,7 @@ struct iwl_scan_results_notif {
* @last_channel: last channel that was scanned
* @tsf_low: TSF timer (lower half) in usecs
* @tsf_high: TSF timer (higher half) in usecs
* @results: a
ll
scan results, only "scanned_channels" of them are valid
* @results: a
rray of
scan results, only "scanned_channels" of them are valid
*/
struct
iwl_scan_complete_notif
{
u8
scanned_channels
;
...
...
@@ -354,11 +348,10 @@ struct iwl_scan_complete_notif {
u8
last_channel
;
__le32
tsf_low
;
__le32
tsf_high
;
struct
iwl_scan_results_notif
results
[
MAX_NUM_SCAN_CHANNELS
];
struct
iwl_scan_results_notif
results
[];
}
__packed
;
/* SCAN_COMPLETE_NTF_API_S_VER_2 */
/* scan offload */
#define IWL_MAX_SCAN_CHANNELS 40
#define IWL_SCAN_MAX_BLACKLIST_LEN 64
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
#define IWL_SCAN_MAX_PROFILES 11
...
...
@@ -423,36 +416,24 @@ enum iwl_scan_offload_channel_flags {
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL
=
BIT
(
25
),
};
/**
* iwl_scan_channel_cfg - SCAN_CHANNEL_CFG_S
* @type: bitmap - see enum iwl_scan_offload_channel_flags.
* 0: passive (0) or active (1) scan.
* 1-20: directed scan to i'th ssid.
* 22: channel width configuation - 1 for narrow.
* 24: full scan.
* 25: partial scan.
* @channel_number: channel number 1-13 etc.
* @iter_count: repetition count for the channel.
* @iter_interval: interval between two innteration on one channel.
* @dwell_time: entry 0 - active scan, entry 1 - passive scan.
/* channel configuration for struct iwl_scan_offload_cfg. Each channels needs:
* __le32 type: bitmap; bits 1-20 are for directed scan to i'th ssid and
* see enum iwl_scan_offload_channel_flags.
* __le16 channel_number: channel number 1-13 etc.
* __le16 iter_count: repetition count for the channel.
* __le32 iter_interval: interval between two innteration on one channel.
* u8 active_dwell.
* u8 passive_dwell.
*/
struct
iwl_scan_channel_cfg
{
__le32
type
[
IWL_MAX_SCAN_CHANNELS
];
__le16
channel_number
[
IWL_MAX_SCAN_CHANNELS
];
__le16
iter_count
[
IWL_MAX_SCAN_CHANNELS
];
__le32
iter_interval
[
IWL_MAX_SCAN_CHANNELS
];
u8
dwell_time
[
IWL_MAX_SCAN_CHANNELS
][
2
];
}
__packed
;
#define IWL_SCAN_CHAN_SIZE 14
/**
* iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S
* @scan_cmd: scan command fixed part
* @channel_cfg: scan channel configuration
* @data: probe request frames (one per band)
* @data: scan channel configuration and probe request frames
*/
struct
iwl_scan_offload_cfg
{
struct
iwl_scan_offload_cmd
scan_cmd
;
struct
iwl_scan_channel_cfg
channel_cfg
;
u8
data
[
0
];
}
__packed
;
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
View file @
5f4ef719
...
...
@@ -67,7 +67,7 @@
* enum iwl_sta_flags - flags for the ADD_STA host command
* @STA_FLG_REDUCED_TX_PWR_CTRL:
* @STA_FLG_REDUCED_TX_PWR_DATA:
* @STA_FLG_
FLG_ANT_MSK: Antenna selection
* @STA_FLG_
DISABLE_TX: set if TX should be disabled
* @STA_FLG_PS: set if STA is in Power Save
* @STA_FLG_INVALID: set if STA is invalid
* @STA_FLG_DLP_EN: Direct Link Protocol is enabled
...
...
@@ -91,10 +91,7 @@ enum iwl_sta_flags {
STA_FLG_REDUCED_TX_PWR_CTRL
=
BIT
(
3
),
STA_FLG_REDUCED_TX_PWR_DATA
=
BIT
(
6
),
STA_FLG_FLG_ANT_A
=
(
1
<<
4
),
STA_FLG_FLG_ANT_B
=
(
2
<<
4
),
STA_FLG_FLG_ANT_MSK
=
(
STA_FLG_FLG_ANT_A
|
STA_FLG_FLG_ANT_B
),
STA_FLG_DISABLE_TX
=
BIT
(
4
),
STA_FLG_PS
=
BIT
(
8
),
STA_FLG_DRAIN_FLOW
=
BIT
(
12
),
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
View file @
5f4ef719
...
...
@@ -548,6 +548,20 @@ struct iwl_beacon_notif {
__le32
ibss_mgr_status
;
}
__packed
;
/**
* struct iwl_extended_beacon_notif - notifies about beacon transmission
* @beacon_notify_hdr: tx response command associated with the beacon
* @tsf: last beacon tsf
* @ibss_mgr_status: whether IBSS is manager
* @gp2: last beacon time in gp2
*/
struct
iwl_extended_beacon_notif
{
struct
iwl_mvm_tx_resp
beacon_notify_hdr
;
__le64
tsf
;
__le32
ibss_mgr_status
;
__le32
gp2
;
}
__packed
;
/* BEACON_NTFY_API_S_VER_5 */
/**
* enum iwl_dump_control - dump (flush) control flags
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
...
...
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
View file @
5f4ef719
...
...
@@ -904,7 +904,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
struct
iwl_mac_beacon_cmd
beacon_cmd
=
{};
struct
ieee80211_tx_info
*
info
;
u32
beacon_skb_len
;
u32
rate
;
u32
rate
,
tx_flags
;
if
(
WARN_ON
(
!
beacon
))
return
-
EINVAL
;
...
...
@@ -914,14 +914,17 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
/* TODO: for now the beacon template id is set to be the mac context id.
* Might be better to handle it as another resource ... */
beacon_cmd
.
template_id
=
cpu_to_le32
((
u32
)
mvmvif
->
id
);
info
=
IEEE80211_SKB_CB
(
beacon
);
/* Set up TX command fields */
beacon_cmd
.
tx
.
len
=
cpu_to_le16
((
u16
)
beacon_skb_len
);
beacon_cmd
.
tx
.
sta_id
=
mvmvif
->
bcast_sta
.
sta_id
;
beacon_cmd
.
tx
.
life_time
=
cpu_to_le32
(
TX_CMD_LIFE_TIME_INFINITE
);
beacon_cmd
.
tx
.
tx_flags
=
cpu_to_le32
(
TX_CMD_FLG_SEQ_CTL
|
TX_CMD_FLG_BT_DIS
|
TX_CMD_FLG_TSF
);
tx_flags
=
TX_CMD_FLG_SEQ_CTL
|
TX_CMD_FLG_TSF
;
tx_flags
|=
iwl_mvm_bt_coex_tx_prio
(
mvm
,
(
void
*
)
beacon
->
data
,
info
,
0
)
<<
TX_CMD_FLG_BT_PRIO_POS
;
beacon_cmd
.
tx
.
tx_flags
=
cpu_to_le32
(
tx_flags
);
mvm
->
mgmt_last_antenna_idx
=
iwl_mvm_next_antenna
(
mvm
,
mvm
->
fw
->
valid_tx_ant
,
...
...
@@ -931,8 +934,6 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
cpu_to_le32
(
BIT
(
mvm
->
mgmt_last_antenna_idx
)
<<
RATE_MCS_ANT_POS
);
info
=
IEEE80211_SKB_CB
(
beacon
);
if
(
info
->
band
==
IEEE80211_BAND_5GHZ
||
vif
->
p2p
)
{
rate
=
IWL_FIRST_OFDM_RATE
;
}
else
{
...
...
@@ -1205,19 +1206,31 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
struct
iwl_device_cmd
*
cmd
)
{
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_beacon_notif
*
beacon
=
(
void
*
)
pkt
->
data
;
u16
status
__maybe_unused
=
le16_to_cpu
(
beacon
->
beacon_notify_hdr
.
status
.
status
);
u32
rate
__maybe_unused
=
le32_to_cpu
(
beacon
->
beacon_notify_hdr
.
initial_rate
);
struct
iwl_mvm_tx_resp
*
beacon_notify_hdr
;
u64
tsf
;
lockdep_assert_held
(
&
mvm
->
mutex
);
IWL_DEBUG_RX
(
mvm
,
"beacon status %#x retries:%d tsf:0x%16llX rate:%d
\n
"
,
status
&
TX_STATUS_MSK
,
beacon
->
beacon_notify_hdr
.
failure_frame
,
le64_to_cpu
(
beacon
->
tsf
),
rate
);
if
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_CAPA_EXTENDED_BEACON
)
{
struct
iwl_extended_beacon_notif
*
beacon
=
(
void
*
)
pkt
->
data
;
beacon_notify_hdr
=
&
beacon
->
beacon_notify_hdr
;
tsf
=
le64_to_cpu
(
beacon
->
tsf
);
mvm
->
ap_last_beacon_gp2
=
le32_to_cpu
(
beacon
->
gp2
);
}
else
{
struct
iwl_beacon_notif
*
beacon
=
(
void
*
)
pkt
->
data
;
beacon_notify_hdr
=
&
beacon
->
beacon_notify_hdr
;
tsf
=
le64_to_cpu
(
beacon
->
tsf
);
}
IWL_DEBUG_RX
(
mvm
,
"beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d
\n
"
,
le16_to_cpu
(
beacon_notify_hdr
->
status
.
status
)
&
TX_STATUS_MSK
,
beacon_notify_hdr
->
failure_frame
,
tsf
,
mvm
->
ap_last_beacon_gp2
,
le32_to_cpu
(
beacon_notify_hdr
->
initial_rate
));
if
(
unlikely
(
mvm
->
csa_vif
&&
mvm
->
csa_vif
->
csa_active
))
{
if
(
!
ieee80211_csa_is_complete
(
mvm
->
csa_vif
))
{
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
View file @
5f4ef719
...
...
@@ -374,6 +374,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
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
|
NL80211_FEATURE_P2P_GO_OPPPS
;
mvm
->
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
;
...
...
@@ -688,6 +689,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
iwl_mvm_restart_cleanup
(
mvm
);
ret
=
iwl_mvm_up
(
mvm
);
if
(
ret
&&
test_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
))
{
/* Something went wrong - we need to finish some cleanup
* that normally iwl_mvm_mac_restart_complete() below
* would do.
*/
clear_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
);
iwl_mvm_d0i3_enable_tx
(
mvm
,
NULL
);
}
mutex_unlock
(
&
mvm
->
mutex
);
return
ret
;
...
...
@@ -1464,6 +1475,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
mutex_lock
(
&
mvm
->
mutex
);
mvmvif
->
ap_ibss_active
=
false
;
mvm
->
ap_last_beacon_gp2
=
0
;
iwl_mvm_bt_coex_vif_change
(
mvm
);
...
...
@@ -1543,7 +1555,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
struct
cfg80211_scan_request
*
req
=
&
hw_req
->
req
;
int
ret
;
if
(
req
->
n_channels
==
0
||
req
->
n_channels
>
MAX_NUM_SCAN_CHANNELS
)
if
(
req
->
n_channels
==
0
||
req
->
n_channels
>
mvm
->
fw
->
ucode_capa
.
n_scan_channels
)
return
-
EINVAL
;
mutex_lock
(
&
mvm
->
mutex
);
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
View file @
5f4ef719
...
...
@@ -235,6 +235,15 @@ enum iwl_mvm_ref_type {
IWL_MVM_REF_COUNT
,
};
enum
iwl_bt_force_ant_mode
{
BT_FORCE_ANT_DIS
=
0
,
BT_FORCE_ANT_AUTO
,
BT_FORCE_ANT_BT
,
BT_FORCE_ANT_WIFI
,
BT_FORCE_ANT_MAX
,
};
/**
* struct iwl_mvm_vif_bf_data - beacon filtering related data
* @bf_enabled: indicates if beacon filtering is enabled
...
...
@@ -629,6 +638,7 @@ struct iwl_mvm {
u32
last_ant_isol
;
u8
last_corun_lut
;
u8
bt_tx_prio
;
enum
iwl_bt_force_ant_mode
bt_force_ant_mode
;
/* Thermal Throttling and CTkill */
struct
iwl_mvm_tt_mgmt
thermal_throttle
;
...
...
@@ -648,6 +658,9 @@ struct iwl_mvm {
bool
ps_disabled
;
struct
ieee80211_vif
*
csa_vif
;
/* system time of last beacon (for AP/GO interface) */
u32
ap_last_beacon_gp2
;
};
/* Extract MVM priv from op_mode and _hw */
...
...
@@ -963,6 +976,7 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
struct
ieee80211_sta
*
sta
);
bool
iwl_mvm_bt_coex_is_mimo_allowed
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
);
bool
iwl_mvm_bt_coex_is_shared_ant_avail
(
struct
iwl_mvm
*
mvm
);
bool
iwl_mvm_bt_coex_is_tpc_allowed
(
struct
iwl_mvm
*
mvm
,
enum
ieee80211_band
band
);
u8
iwl_mvm_bt_coex_tx_prio
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_hdr
*
hdr
,
...
...
drivers/net/wireless/iwlwifi/mvm/nvm.c
View file @
5f4ef719
...
...
@@ -69,7 +69,9 @@
/* Default NVM size to read */
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
#define IWL_MAX_NVM_SECTION_SIZE 7000
#define IWL_MAX_NVM_SECTION_SIZE 0x1b58
#define IWL_MAX_NVM_8000A_SECTION_SIZE 0xffc
#define IWL_MAX_NVM_8000B_SECTION_SIZE 0x1ffc
#define NVM_WRITE_OPCODE 1
#define NVM_READ_OPCODE 0
...
...
@@ -219,7 +221,7 @@ static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
* without overflowing, so no check is needed.
*/
static
int
iwl_nvm_read_section
(
struct
iwl_mvm
*
mvm
,
u16
section
,
u8
*
data
)
u8
*
data
,
u32
size_read
)
{
u16
length
,
offset
=
0
;
int
ret
;
...
...
@@ -231,6 +233,13 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
/* Read the NVM until exhausted (reading less than requested) */
while
(
ret
==
length
)
{
/* Check no memory assumptions fail and cause an overflow */
if
((
size_read
+
offset
+
length
)
>
mvm
->
cfg
->
base_params
->
eeprom_size
)
{
IWL_ERR
(
mvm
,
"EEPROM size is too small for NVM
\n
"
);
return
-
ENOBUFS
;
}
ret
=
iwl_nvm_read_chunk
(
mvm
,
section
,
offset
,
length
,
data
);
if
(
ret
<
0
)
{
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
...
...
@@ -326,6 +335,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
u8
data
[];
}
*
file_sec
;
const
u8
*
eof
,
*
temp
;
int
max_section_size
;
#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
#define NVM_WORD2_ID(x) (x >> 12)
...
...
@@ -334,6 +344,14 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
"Read from external NVM
\n
"
);
/* 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 */
max_section_size
=
IWL_MAX_NVM_8000A_SECTION_SIZE
;
else
/* Family 8000 B-step */
max_section_size
=
IWL_MAX_NVM_8000B_SECTION_SIZE
;
/*
* Obtain NVM image via request_firmware. Since we already used
* request_firmware_nowait() for the firmware binary load and only
...
...
@@ -392,7 +410,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
le16_to_cpu
(
file_sec
->
word1
));
}
if
(
section_size
>
IWL_MAX_NVM_SECTION_SIZE
)
{
if
(
section_size
>
max_section_size
)
{
IWL_ERR
(
mvm
,
"ERROR - section too large (%d)
\n
"
,
section_size
);
ret
=
-
EINVAL
;
...
...
@@ -459,6 +477,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
int
iwl_nvm_init
(
struct
iwl_mvm
*
mvm
,
bool
read_nvm_from_nic
)
{
int
ret
,
section
;
u32
size_read
=
0
;
u8
*
nvm_buffer
,
*
temp
;
if
(
WARN_ON_ONCE
(
mvm
->
cfg
->
nvm_hw_section_num
>=
NVM_MAX_NUM_SECTIONS
))
...
...
@@ -475,9 +494,11 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
return
-
ENOMEM
;
for
(
section
=
0
;
section
<
NVM_MAX_NUM_SECTIONS
;
section
++
)
{
/* we override the constness for initial read */
ret
=
iwl_nvm_read_section
(
mvm
,
section
,
nvm_buffer
);
ret
=
iwl_nvm_read_section
(
mvm
,
section
,
nvm_buffer
,
size_read
);
if
(
ret
<
0
)
continue
;
size_read
+=
ret
;
temp
=
kmemdup
(
nvm_buffer
,
ret
,
GFP_KERNEL
);
if
(
!
temp
)
{
ret
=
-
ENOMEM
;
...
...
drivers/net/wireless/iwlwifi/mvm/ops.c
View file @
5f4ef719
...
...
@@ -504,7 +504,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
scan_size
=
sizeof
(
struct
iwl_scan_cmd
)
+
mvm
->
fw
->
ucode_capa
.
max_probe_length
+
(
MAX_NUM_SCAN_CHANNELS
*
sizeof
(
struct
iwl_scan_channel
));
(
mvm
->
fw
->
ucode_capa
.
n_scan_channels
*
sizeof
(
struct
iwl_scan_channel
));
mvm
->
scan_cmd
=
kmalloc
(
scan_size
,
GFP_KERNEL
);
if
(
!
mvm
->
scan_cmd
)
goto
out_free
;
...
...
@@ -826,6 +827,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
{
struct
iwl_fw_error_dump_file
*
dump_file
;
struct
iwl_fw_error_dump_data
*
dump_data
;
struct
iwl_fw_error_dump_info
*
dump_info
;
u32
file_len
;
u32
trans_len
;
...
...
@@ -834,10 +836,11 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
if
(
mvm
->
fw_error_dump
)
return
;
file_len
=
mvm
->
fw_error_sram_len
+
file_len
=
sizeof
(
*
dump_file
)
+
sizeof
(
*
dump_data
)
*
3
+
mvm
->
fw_error_sram_len
+
mvm
->
fw_error_rxf_len
+
sizeof
(
*
dump_file
)
+
sizeof
(
*
dump_data
)
*
2
;
sizeof
(
*
dump_info
);
trans_len
=
iwl_trans_dump_data
(
mvm
->
trans
,
NULL
,
0
);
if
(
trans_len
)
...
...
@@ -852,11 +855,27 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
dump_file
->
barker
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_BARKER
);
dump_file
->
file_len
=
cpu_to_le32
(
file_len
);
dump_data
=
(
void
*
)
dump_file
->
data
;
dump_data
->
type
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_DEV_FW_INFO
);
dump_data
->
len
=
cpu_to_le32
(
sizeof
(
*
dump_info
));
dump_info
=
(
void
*
)
dump_data
->
data
;
dump_info
->
device_family
=
mvm
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_7000
?
cpu_to_le32
(
IWL_FW_ERROR_DUMP_FAMILY_7
)
:
cpu_to_le32
(
IWL_FW_ERROR_DUMP_FAMILY_8
);
memcpy
(
dump_info
->
fw_human_readable
,
mvm
->
fw
->
human_readable
,
sizeof
(
dump_info
->
fw_human_readable
));
strncpy
(
dump_info
->
dev_human_readable
,
mvm
->
cfg
->
name
,
sizeof
(
dump_info
->
dev_human_readable
));
strncpy
(
dump_info
->
bus_human_readable
,
mvm
->
dev
->
bus
->
name
,
sizeof
(
dump_info
->
bus_human_readable
));
dump_data
=
iwl_fw_error_next_data
(
dump_data
);
dump_data
->
type
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_RXF
);
dump_data
->
len
=
cpu_to_le32
(
mvm
->
fw_error_rxf_len
);
memcpy
(
dump_data
->
data
,
mvm
->
fw_error_rxf
,
mvm
->
fw_error_rxf_len
);
dump_data
=
iwl_
mvm_
fw_error_next_data
(
dump_data
);
dump_data
=
iwl_fw_error_next_data
(
dump_data
);
dump_data
->
type
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_SRAM
);
dump_data
->
len
=
cpu_to_le32
(
mvm
->
fw_error_sram_len
);
...
...
@@ -876,7 +895,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
mvm
->
fw_error_sram_len
=
0
;
if
(
trans_len
)
{
void
*
buf
=
iwl_
mvm_
fw_error_next_data
(
dump_data
);
void
*
buf
=
iwl_fw_error_next_data
(
dump_data
);
u32
real_trans_len
=
iwl_trans_dump_data
(
mvm
->
trans
,
buf
,
trans_len
);
dump_data
=
(
void
*
)((
u8
*
)
buf
+
real_trans_len
);
...
...
drivers/net/wireless/iwlwifi/mvm/scan.c
View file @
5f4ef719
...
...
@@ -275,7 +275,7 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
static
void
iwl_mvm_scan_calc_params
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
int
n_ssids
,
int
n_ssids
,
u32
flags
,
struct
iwl_mvm_scan_params
*
params
)
{
bool
global_bound
=
false
;
...
...
@@ -297,6 +297,9 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
params
->
max_out_time
=
250
;
}
if
(
flags
&
NL80211_SCAN_FLAG_LOW_PRIORITY
)
params
->
max_out_time
=
200
;
not_bound:
for
(
band
=
IEEE80211_BAND_2GHZ
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
...
...
@@ -333,16 +336,14 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
IWL_DEBUG_SCAN
(
mvm
,
"Handling mac80211 scan request
\n
"
);
mvm
->
scan_status
=
IWL_MVM_SCAN_OS
;
memset
(
cmd
,
0
,
sizeof
(
struct
iwl_scan_cmd
)
+
mvm
->
fw
->
ucode_capa
.
max_probe_length
+
(
MAX_NUM_SCAN_CHANNELS
*
sizeof
(
struct
iwl_scan_channel
)));
memset
(
cmd
,
0
,
ksize
(
cmd
));
cmd
->
channel_count
=
(
u8
)
req
->
n_channels
;
cmd
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
cmd
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
cmd
->
rxchain_sel_flags
=
iwl_mvm_scan_rx_chain
(
mvm
);
iwl_mvm_scan_calc_params
(
mvm
,
vif
,
req
->
n_ssids
,
&
params
);
iwl_mvm_scan_calc_params
(
mvm
,
vif
,
req
->
n_ssids
,
req
->
flags
,
&
params
);
cmd
->
max_out_time
=
cpu_to_le32
(
params
.
max_out_time
);
cmd
->
suspend_time
=
cpu_to_le32
(
params
.
suspend_time
);
if
(
params
.
passive_fragmented
)
...
...
@@ -597,9 +598,7 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
struct
iwl_scan_offload_cmd
*
scan
,
struct
iwl_mvm_scan_params
*
params
)
{
scan
->
channel_count
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
+
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
scan
->
channel_count
=
req
->
n_channels
;
scan
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
scan
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
scan
->
good_CRC_th
=
IWL_GOOD_CRC_TH_DEFAULT
;
...
...
@@ -676,68 +675,50 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
static
void
iwl_build_channel_cfg
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
,
struct
iwl_scan_channel_cfg
*
channels
,
u8
*
channels_buffer
,
enum
ieee80211_band
band
,
int
*
head
,
int
*
tail
,
int
*
head
,
u32
ssid_bitmap
,
struct
iwl_mvm_scan_params
*
params
)
{
struct
ieee80211_supported_band
*
s_band
;
int
n_channels
=
req
->
n_channels
;
int
i
,
j
,
index
=
0
;
bool
partial
;
/*
* We have to configure all supported channels, even if we don't want to
* scan on them, but we have to send channels in the order that we want
* to scan. So add requested channels to head of the list and others to
* the end.
*/
s_band
=
&
mvm
->
nvm_data
->
bands
[
band
];
u32
n_channels
=
mvm
->
fw
->
ucode_capa
.
n_scan_channels
;
__le32
*
type
=
(
__le32
*
)
channels_buffer
;
__le16
*
channel_number
=
(
__le16
*
)(
type
+
n_channels
);
__le16
*
iter_count
=
channel_number
+
n_channels
;
__le32
*
iter_interval
=
(
__le32
*
)(
iter_count
+
n_channels
);
u8
*
active_dwell
=
(
u8
*
)(
iter_interval
+
n_channels
);
u8
*
passive_dwell
=
active_dwell
+
n_channels
;
int
i
,
index
=
0
;
for
(
i
=
0
;
i
<
req
->
n_channels
;
i
++
)
{
struct
ieee80211_channel
*
chan
=
req
->
channels
[
i
];
if
(
chan
->
band
!=
band
)
continue
;
for
(
i
=
0
;
i
<
s_band
->
n_channels
&&
*
head
<=
*
tail
;
i
++
)
{
partial
=
false
;
for
(
j
=
0
;
j
<
n_channels
;
j
++
)
if
(
s_band
->
channels
[
i
].
center_freq
==
req
->
channels
[
j
]
->
center_freq
)
{
index
=
*
head
;
(
*
head
)
++
;
/*
* Channels that came with the request will be
* in partial scan .
*/
partial
=
true
;
break
;
}
if
(
!
partial
)
{
index
=
*
tail
;
(
*
tail
)
--
;
}
channels
->
channel_number
[
index
]
=
cpu_to_le16
(
ieee80211_frequency_to_channel
(
s_band
->
channels
[
i
].
center_freq
));
channels
->
dwell_time
[
index
][
0
]
=
params
->
dwell
[
band
].
active
;
channels
->
dwell_time
[
index
][
1
]
=
params
->
dwell
[
band
].
passive
;
channels
->
iter_count
[
index
]
=
cpu_to_le16
(
1
);
channels
->
iter_interval
[
index
]
=
0
;
channel_number
[
index
]
=
cpu_to_le16
(
chan
->
hw_value
);
active_dwell
[
index
]
=
params
->
dwell
[
band
].
active
;
passive_dwell
[
index
]
=
params
->
dwell
[
band
].
passive
;
iter_count
[
index
]
=
cpu_to_le16
(
1
);
iter_interval
[
index
]
=
0
;
if
(
!
(
s_band
->
channels
[
i
].
flags
&
IEEE80211_CHAN_NO_IR
))
channels
->
type
[
index
]
|=
if
(
!
(
chan
->
flags
&
IEEE80211_CHAN_NO_IR
))
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE
);
channels
->
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_FULL
);
if
(
partial
)
channels
->
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL
);
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_FULL
|
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL
);
if
(
s_band
->
channels
[
i
].
flags
&
IEEE80211_CHAN_NO_HT40
)
channels
->
type
[
index
]
|=
if
(
chan
->
flags
&
IEEE80211_CHAN_NO_HT40
)
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_NARROW
);
/* scan for all SSIDs from req->ssids */
channels
->
type
[
index
]
|=
cpu_to_le32
(
ssid_bitmap
);
type
[
index
]
|=
cpu_to_le32
(
ssid_bitmap
);
}
}
...
...
@@ -749,10 +730,10 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
int
band_2ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
;
int
band_5ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
int
head
=
0
;
int
tail
=
band_2ghz
+
band_5ghz
-
1
;
u32
ssid_bitmap
;
int
cmd_len
;
int
ret
;
u8
*
probes
;
struct
iwl_scan_offload_cfg
*
scan_cfg
;
struct
iwl_host_cmd
cmd
=
{
...
...
@@ -763,13 +744,17 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
lockdep_assert_held
(
&
mvm
->
mutex
);
cmd_len
=
sizeof
(
struct
iwl_scan_offload_cfg
)
+
mvm
->
fw
->
ucode_capa
.
n_scan_channels
*
IWL_SCAN_CHAN_SIZE
+
2
*
SCAN_OFFLOAD_PROBE_REQ_SIZE
;
scan_cfg
=
kzalloc
(
cmd_len
,
GFP_KERNEL
);
if
(
!
scan_cfg
)
return
-
ENOMEM
;
iwl_mvm_scan_calc_params
(
mvm
,
vif
,
req
->
n_ssids
,
&
params
);
probes
=
scan_cfg
->
data
+
mvm
->
fw
->
ucode_capa
.
n_scan_channels
*
IWL_SCAN_CHAN_SIZE
;
iwl_mvm_scan_calc_params
(
mvm
,
vif
,
req
->
n_ssids
,
0
,
&
params
);
iwl_build_scan_cmd
(
mvm
,
vif
,
req
,
&
scan_cfg
->
scan_cmd
,
&
params
);
scan_cfg
->
scan_cmd
.
len
=
cpu_to_le16
(
cmd_len
);
...
...
@@ -779,19 +764,19 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
IEEE80211_BAND_2GHZ
,
&
scan_cfg
->
scan_cmd
.
tx_cmd
[
0
],
scan_cfg
->
data
);
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
IEEE80211_BAND_2GHZ
,
&
head
,
&
tail
,
probes
);
iwl_build_channel_cfg
(
mvm
,
req
,
scan_cfg
->
data
,
IEEE80211_BAND_2GHZ
,
&
head
,
ssid_bitmap
,
&
params
);
}
if
(
band_5ghz
)
{
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
IEEE80211_BAND_5GHZ
,
&
scan_cfg
->
scan_cmd
.
tx_cmd
[
1
],
scan_cfg
->
data
+
probes
+
SCAN_OFFLOAD_PROBE_REQ_SIZE
);
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
IEEE80211_BAND_5GHZ
,
&
head
,
&
tail
,
iwl_build_channel_cfg
(
mvm
,
req
,
scan_cfg
->
data
,
IEEE80211_BAND_5GHZ
,
&
head
,
ssid_bitmap
,
&
params
);
}
...
...
drivers/net/wireless/iwlwifi/mvm/sta.c
View file @
5f4ef719
...
...
@@ -1448,3 +1448,23 @@ int iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
return
0
;
}
void
iwl_mvm_sta_modify_disable_tx
(
struct
iwl_mvm
*
mvm
,
struct
iwl_mvm_sta
*
mvmsta
,
bool
disable
)
{
struct
iwl_mvm_add_sta_cmd
cmd
=
{
.
add_modify
=
STA_MODE_MODIFY
,
.
sta_id
=
mvmsta
->
sta_id
,
.
station_flags
=
disable
?
cpu_to_le32
(
STA_FLG_DISABLE_TX
)
:
0
,
.
station_flags_msk
=
cpu_to_le32
(
STA_FLG_DISABLE_TX
),
.
mac_id_n_color
=
cpu_to_le32
(
mvmsta
->
mac_id_n_color
),
};
int
ret
;
if
(
!
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_DISABLE_STA_TX
))
return
;
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
ADD_STA
,
CMD_ASYNC
,
sizeof
(
cmd
),
&
cmd
);
if
(
ret
)
IWL_ERR
(
mvm
,
"Failed to send ADD_STA command (%d)
\n
"
,
ret
);
}
drivers/net/wireless/iwlwifi/mvm/sta.h
View file @
5f4ef719
...
...
@@ -404,5 +404,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
bool
agg
);
int
iwl_mvm_drain_sta
(
struct
iwl_mvm
*
mvm
,
struct
iwl_mvm_sta
*
mvmsta
,
bool
drain
);
void
iwl_mvm_sta_modify_disable_tx
(
struct
iwl_mvm
*
mvm
,
struct
iwl_mvm_sta
*
mvmsta
,
bool
disable
);
#endif
/* __sta_h__ */
drivers/net/wireless/iwlwifi/mvm/tx.c
View file @
5f4ef719
...
...
@@ -205,7 +205,13 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
mvm
->
mgmt_last_antenna_idx
=
iwl_mvm_next_antenna
(
mvm
,
mvm
->
fw
->
valid_tx_ant
,
mvm
->
mgmt_last_antenna_idx
);
rate_flags
=
BIT
(
mvm
->
mgmt_last_antenna_idx
)
<<
RATE_MCS_ANT_POS
;
if
(
info
->
band
==
IEEE80211_BAND_2GHZ
&&
!
iwl_mvm_bt_coex_is_shared_ant_avail
(
mvm
))
rate_flags
=
BIT
(
ANT_A
)
<<
RATE_MCS_ANT_POS
;
else
rate_flags
=
BIT
(
mvm
->
mgmt_last_antenna_idx
)
<<
RATE_MCS_ANT_POS
;
/* Set CCK flag as needed */
if
((
rate_idx
>=
IWL_FIRST_CCK_RATE
)
&&
(
rate_idx
<=
IWL_LAST_CCK_RATE
))
...
...
drivers/net/wireless/iwlwifi/pcie/internal.h
View file @
5f4ef719
...
...
@@ -260,6 +260,9 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
* @wd_timeout: queue watchdog timeout (jiffies)
* @reg_lock: protect hw register access
* @cmd_in_flight: true when we have a host command in flight
* @fw_mon_phys: physical address of the buffer for the firmware monitor
* @fw_mon_page: points to the first page of the buffer for the firmware monitor
* @fw_mon_size: size of the buffer for the firmware monitor
*/
struct
iwl_trans_pcie
{
struct
iwl_rxq
rxq
;
...
...
@@ -312,6 +315,10 @@ struct iwl_trans_pcie {
/*protect hw register */
spinlock_t
reg_lock
;
bool
cmd_in_flight
;
dma_addr_t
fw_mon_phys
;
struct
page
*
fw_mon_page
;
u32
fw_mon_size
;
};
#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
View file @
5f4ef719
...
...
@@ -76,6 +76,68 @@
#include "iwl-fw-error-dump.h"
#include "internal.h"
static
void
iwl_pcie_free_fw_monitor
(
struct
iwl_trans
*
trans
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
if
(
!
trans_pcie
->
fw_mon_page
)
return
;
dma_unmap_page
(
trans
->
dev
,
trans_pcie
->
fw_mon_phys
,
trans_pcie
->
fw_mon_size
,
DMA_FROM_DEVICE
);
__free_pages
(
trans_pcie
->
fw_mon_page
,
get_order
(
trans_pcie
->
fw_mon_size
));
trans_pcie
->
fw_mon_page
=
NULL
;
trans_pcie
->
fw_mon_phys
=
0
;
trans_pcie
->
fw_mon_size
=
0
;
}
static
void
iwl_pcie_alloc_fw_monitor
(
struct
iwl_trans
*
trans
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
struct
page
*
page
;
dma_addr_t
phys
;
u32
size
;
u8
power
;
if
(
trans_pcie
->
fw_mon_page
)
{
dma_sync_single_for_device
(
trans
->
dev
,
trans_pcie
->
fw_mon_phys
,
trans_pcie
->
fw_mon_size
,
DMA_FROM_DEVICE
);
return
;
}
phys
=
0
;
for
(
power
=
26
;
power
>=
11
;
power
--
)
{
int
order
;
size
=
BIT
(
power
);
order
=
get_order
(
size
);
page
=
alloc_pages
(
__GFP_COMP
|
__GFP_NOWARN
|
__GFP_ZERO
,
order
);
if
(
!
page
)
continue
;
phys
=
dma_map_page
(
trans
->
dev
,
page
,
0
,
PAGE_SIZE
<<
order
,
DMA_FROM_DEVICE
);
if
(
dma_mapping_error
(
trans
->
dev
,
phys
))
{
__free_pages
(
page
,
order
);
continue
;
}
IWL_INFO
(
trans
,
"Allocated 0x%08x bytes (order %d) for firmware monitor.
\n
"
,
size
,
order
);
break
;
}
if
(
!
page
)
return
;
trans_pcie
->
fw_mon_page
=
page
;
trans_pcie
->
fw_mon_phys
=
phys
;
trans_pcie
->
fw_mon_size
=
size
;
}
static
u32
iwl_trans_pcie_read_shr
(
struct
iwl_trans
*
trans
,
u32
reg
)
{
iwl_write32
(
trans
,
HEEP_CTRL_WRD_PCIEX_CTRL_REG
,
...
...
@@ -675,6 +737,7 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
static
int
iwl_pcie_load_given_ucode
(
struct
iwl_trans
*
trans
,
const
struct
fw_img
*
image
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
int
ret
=
0
;
int
first_ucode_section
;
...
...
@@ -733,6 +796,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
return
ret
;
}
/* supported for 7000 only for the moment */
if
(
iwlwifi_mod_params
.
fw_monitor
&&
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_7000
)
{
iwl_pcie_alloc_fw_monitor
(
trans
);
if
(
trans_pcie
->
fw_mon_size
)
{
iwl_write_prph
(
trans
,
MON_BUFF_BASE_ADDR
,
trans_pcie
->
fw_mon_phys
>>
4
);
iwl_write_prph
(
trans
,
MON_BUFF_END_ADDR
,
(
trans_pcie
->
fw_mon_phys
+
trans_pcie
->
fw_mon_size
)
>>
4
);
}
}
/* release CPU reset */
if
(
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_8000
)
iwl_write_prph
(
trans
,
RELEASE_CPU_RESET
,
RELEASE_CPU_RESET_BIT
);
...
...
@@ -1126,6 +1203,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
if
(
trans_pcie
->
napi
.
poll
)
netif_napi_del
(
&
trans_pcie
->
napi
);
iwl_pcie_free_fw_monitor
(
trans
);
kfree
(
trans
);
}
...
...
@@ -1494,10 +1573,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
txq
=
&
trans_pcie
->
txq
[
cnt
];
q
=
&
txq
->
q
;
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"hwq %.2d: read=%u write=%u use=%d stop=%d
\n
"
,
"hwq %.2d: read=%u write=%u use=%d stop=%d
need_update=%d%s
\n
"
,
cnt
,
q
->
read_ptr
,
q
->
write_ptr
,
!!
test_bit
(
cnt
,
trans_pcie
->
queue_used
),
!!
test_bit
(
cnt
,
trans_pcie
->
queue_stopped
));
!!
test_bit
(
cnt
,
trans_pcie
->
queue_stopped
),
txq
->
need_update
,
(
cnt
==
trans_pcie
->
cmd_queue
?
" HCMD"
:
""
));
}
ret
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
kfree
(
buf
);
...
...
@@ -1519,6 +1600,10 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
rxq
->
read
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"write: %u
\n
"
,
rxq
->
write
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"write_actual: %u
\n
"
,
rxq
->
write_actual
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"need_update: %d
\n
"
,
rxq
->
need_update
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"free_count: %u
\n
"
,
rxq
->
free_count
);
if
(
rxq
->
rb_stts
)
{
...
...
@@ -1698,10 +1783,15 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
u32
len
;
int
i
,
ptr
;
len
=
sizeof
(
*
data
)
+
cmdq
->
q
.
n_window
*
(
sizeof
(
*
txcmd
)
+
TFD_MAX_PAYLOAD_SIZE
);
if
(
trans_pcie
->
fw_mon_page
)
len
+=
sizeof
(
*
data
)
+
sizeof
(
struct
iwl_fw_error_fw_mon
)
+
trans_pcie
->
fw_mon_size
;
if
(
!
buf
)
return
sizeof
(
*
data
)
+
cmdq
->
q
.
n_window
*
(
sizeof
(
*
txcmd
)
+
TFD_MAX_PAYLOAD_SIZE
);
return
len
;
len
=
0
;
data
=
buf
;
...
...
@@ -1729,7 +1819,40 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
spin_unlock_bh
(
&
cmdq
->
lock
);
data
->
len
=
cpu_to_le32
(
len
);
return
sizeof
(
*
data
)
+
len
;
len
+=
sizeof
(
*
data
);
if
(
trans_pcie
->
fw_mon_page
)
{
struct
iwl_fw_error_fw_mon
*
fw_mon_data
;
data
=
iwl_fw_error_next_data
(
data
);
data
->
type
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_FW_MONITOR
);
data
->
len
=
cpu_to_le32
(
trans_pcie
->
fw_mon_size
+
sizeof
(
*
fw_mon_data
));
fw_mon_data
=
(
void
*
)
data
->
data
;
fw_mon_data
->
fw_mon_wr_ptr
=
cpu_to_le32
(
iwl_read_prph
(
trans
,
MON_BUFF_WRPTR
));
fw_mon_data
->
fw_mon_cycle_cnt
=
cpu_to_le32
(
iwl_read_prph
(
trans
,
MON_BUFF_CYCLE_CNT
));
fw_mon_data
->
fw_mon_base_ptr
=
cpu_to_le32
(
iwl_read_prph
(
trans
,
MON_BUFF_BASE_ADDR
));
/*
* The firmware is now asserted, it won't write anything to
* the buffer. CPU can take ownership to fetch the data.
* The buffer will be handed back to the device before the
* firmware will be restarted.
*/
dma_sync_single_for_cpu
(
trans
->
dev
,
trans_pcie
->
fw_mon_phys
,
trans_pcie
->
fw_mon_size
,
DMA_FROM_DEVICE
);
memcpy
(
fw_mon_data
->
data
,
page_address
(
trans_pcie
->
fw_mon_page
),
trans_pcie
->
fw_mon_size
);
len
+=
sizeof
(
*
data
)
+
sizeof
(
*
fw_mon_data
)
+
trans_pcie
->
fw_mon_size
;
}
return
len
;
}
#else
static
int
iwl_trans_pcie_dbgfs_register
(
struct
iwl_trans
*
trans
,
...
...
@@ -1870,6 +1993,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
}
trans
->
hw_rev
=
iwl_read32
(
trans
,
CSR_HW_REV
);
/*
* In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
* changed, and now the revision step also includes bit 0-1 (no more
* "dash" value). To keep hw_rev backwards compatible - we'll store it
* in the old format.
*/
if
(
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_8000
)
trans
->
hw_rev
=
(
trans
->
hw_rev
&
0xfff0
)
|
((
trans
->
hw_rev
<<
2
)
&
0xc
);
trans
->
hw_id
=
(
pdev
->
device
<<
16
)
+
pdev
->
subsystem_device
;
snprintf
(
trans
->
hw_id_str
,
sizeof
(
trans
->
hw_id_str
),
"PCI ID: 0x%04X:0x%04X"
,
pdev
->
device
,
pdev
->
subsystem_device
);
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
View file @
5f4ef719
...
...
@@ -1438,6 +1438,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
spin_unlock_irqrestore
(
&
trans_pcie
->
reg_lock
,
flags
);
trans_pcie
->
cmd_in_flight
=
false
;
IWL_ERR
(
trans
,
"Failed to wake NIC for hcmd
\n
"
);
idx
=
-
EIO
;
goto
out
;
}
...
...
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