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 @@
...
@@ -40,6 +40,10 @@
#include "commands.h"
#include "commands.h"
#include "power.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.
* 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,
...
@@ -288,6 +292,11 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
bool
enabled
=
priv
->
hw
->
conf
.
flags
&
IEEE80211_CONF_PS
;
bool
enabled
=
priv
->
hw
->
conf
.
flags
&
IEEE80211_CONF_PS
;
int
dtimper
;
int
dtimper
;
if
(
force_cam
)
{
iwl_power_sleep_cam_cmd
(
priv
,
cmd
);
return
;
}
dtimper
=
priv
->
hw
->
conf
.
ps_dtim_period
?:
1
;
dtimper
=
priv
->
hw
->
conf
.
ps_dtim_period
?:
1
;
if
(
priv
->
wowlan
)
if
(
priv
->
wowlan
)
...
...
drivers/net/wireless/iwlwifi/iwl-8000.c
View file @
5f4ef719
...
@@ -67,7 +67,7 @@
...
@@ -67,7 +67,7 @@
#include "iwl-agn-hw.h"
#include "iwl-agn-hw.h"
/* Highest firmware API version supported */
/* Highest firmware API version supported */
#define IWL8000_UCODE_API_MAX
8
#define IWL8000_UCODE_API_MAX
9
/* Oldest version we won't warn about */
/* Oldest version we won't warn about */
#define IWL8000_UCODE_API_OK 8
#define IWL8000_UCODE_API_OK 8
...
@@ -119,10 +119,9 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
...
@@ -119,10 +119,9 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
.
ht_params
=
&
iwl8000_ht_params
,
.
ht_params
=
&
iwl8000_ht_params
,
.
nvm_ver
=
IWL8000_NVM_VERSION
,
.
nvm_ver
=
IWL8000_NVM_VERSION
,
.
nvm_calib_ver
=
IWL8000_TX_POWER_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"
,
.
name
=
"Intel(R) Dual Band Wireless-AC 8260"
,
.
fw_name_pre
=
IWL8000_FW_PRE
,
.
fw_name_pre
=
IWL8000_FW_PRE
,
IWL_DEVICE_8000
,
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;
...
@@ -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_2n_cfg
;
extern
const
struct
iwl_cfg
iwl7265_n_cfg
;
extern
const
struct
iwl_cfg
iwl7265_n_cfg
;
extern
const
struct
iwl_cfg
iwl8260_2ac_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
/* CONFIG_IWLMVM */
#endif
/* __IWL_CONFIG_H__ */
#endif
/* __IWL_CONFIG_H__ */
drivers/net/wireless/iwlwifi/iwl-drv.c
View file @
5f4ef719
...
@@ -155,6 +155,8 @@ static struct iwlwifi_opmode_table {
...
@@ -155,6 +155,8 @@ static struct iwlwifi_opmode_table {
[
MVM_OP_MODE
]
=
{
.
name
=
"iwlmvm"
,
.
ops
=
NULL
},
[
MVM_OP_MODE
]
=
{
.
name
=
"iwlmvm"
,
.
ops
=
NULL
},
};
};
#define IWL_DEFAULT_SCAN_CHANNELS 40
/*
/*
* struct fw_sec: Just for the image parsing proccess.
* struct fw_sec: Just for the image parsing proccess.
* For the fw storage we are using struct fw_desc.
* For the fw storage we are using struct fw_desc.
...
@@ -565,6 +567,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
...
@@ -565,6 +567,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
}
}
drv
->
fw
.
ucode_ver
=
le32_to_cpu
(
ucode
->
ver
);
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
);
build
=
le32_to_cpu
(
ucode
->
build
);
if
(
build
)
if
(
build
)
...
@@ -819,6 +823,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
...
@@ -819,6 +823,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
if
(
iwl_store_cscheme
(
&
drv
->
fw
,
tlv_data
,
tlv_len
))
if
(
iwl_store_cscheme
(
&
drv
->
fw
,
tlv_data
,
tlv_len
))
goto
invalid_tlv_len
;
goto
invalid_tlv_len
;
break
;
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:
default:
IWL_DEBUG_INFO
(
drv
,
"unknown TLV: %d
\n
"
,
tlv_type
);
IWL_DEBUG_INFO
(
drv
,
"unknown TLV: %d
\n
"
,
tlv_type
);
break
;
break
;
...
@@ -973,6 +983,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
...
@@ -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
.
max_probe_length
=
IWL_DEFAULT_MAX_PROBE_LENGTH
;
fw
->
ucode_capa
.
standard_phy_calibration_size
=
fw
->
ucode_capa
.
standard_phy_calibration_size
=
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE
;
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE
;
fw
->
ucode_capa
.
n_scan_channels
=
IWL_DEFAULT_SCAN_CHANNELS
;
if
(
!
api_ok
)
if
(
!
api_ok
)
api_ok
=
api_max
;
api_ok
=
api_max
;
...
@@ -1394,3 +1405,7 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
...
@@ -1394,3 +1405,7 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
int
,
S_IRUGO
);
int
,
S_IRUGO
);
MODULE_PARM_DESC
(
power_level
,
MODULE_PARM_DESC
(
power_level
,
"default power save level (range from 1 - 5, default: 1)"
);
"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,
...
@@ -779,7 +779,6 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
if
(
cfg
->
ht_params
->
ht40_bands
&
BIT
(
band
))
{
if
(
cfg
->
ht_params
->
ht40_bands
&
BIT
(
band
))
{
ht_info
->
cap
|=
IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
ht_info
->
cap
|=
IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
ht_info
->
cap
|=
IEEE80211_HT_CAP_SGI_40
;
ht_info
->
cap
|=
IEEE80211_HT_CAP_SGI_40
;
ht_info
->
mcs
.
rx_mask
[
4
]
=
0x01
;
max_bit_rate
=
MAX_BIT_RATE_40_MHZ
;
max_bit_rate
=
MAX_BIT_RATE_40_MHZ
;
}
}
...
...
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
View file @
5f4ef719
...
@@ -74,12 +74,17 @@
...
@@ -74,12 +74,17 @@
* @IWL_FW_ERROR_DUMP_RXF:
* @IWL_FW_ERROR_DUMP_RXF:
* @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
* @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
* &struct iwl_fw_error_dump_txcmd packets
* &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
{
enum
iwl_fw_error_dump_type
{
IWL_FW_ERROR_DUMP_SRAM
=
0
,
IWL_FW_ERROR_DUMP_SRAM
=
0
,
IWL_FW_ERROR_DUMP_REG
=
1
,
IWL_FW_ERROR_DUMP_REG
=
1
,
IWL_FW_ERROR_DUMP_RXF
=
2
,
IWL_FW_ERROR_DUMP_RXF
=
2
,
IWL_FW_ERROR_DUMP_TXCMD
=
3
,
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
,
IWL_FW_ERROR_DUMP_MAX
,
};
};
...
@@ -120,13 +125,50 @@ struct iwl_fw_error_dump_txcmd {
...
@@ -120,13 +125,50 @@ struct iwl_fw_error_dump_txcmd {
u8
data
[];
u8
data
[];
}
__packed
;
}
__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
* @data: previous data block
* Returns: next data block
* Returns: next data block
*/
*/
static
inline
struct
iwl_fw_error_dump_data
*
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
));
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 {
...
@@ -128,6 +128,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_CSCHEME
=
28
,
IWL_UCODE_TLV_CSCHEME
=
28
,
IWL_UCODE_TLV_API_CHANGES_SET
=
29
,
IWL_UCODE_TLV_API_CHANGES_SET
=
29
,
IWL_UCODE_TLV_ENABLED_CAPABILITIES
=
30
,
IWL_UCODE_TLV_ENABLED_CAPABILITIES
=
30
,
IWL_UCODE_TLV_N_SCAN_CHANNELS
=
31
,
};
};
struct
iwl_ucode_tlv
{
struct
iwl_ucode_tlv
{
...
@@ -137,6 +138,7 @@ struct iwl_ucode_tlv {
...
@@ -137,6 +138,7 @@ struct iwl_ucode_tlv {
};
};
#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
#define FW_VER_HUMAN_READABLE_SZ 64
struct
iwl_tlv_ucode_header
{
struct
iwl_tlv_ucode_header
{
/*
/*
...
@@ -147,7 +149,7 @@ struct iwl_tlv_ucode_header {
...
@@ -147,7 +149,7 @@ struct iwl_tlv_ucode_header {
*/
*/
__le32
zero
;
__le32
zero
;
__le32
magic
;
__le32
magic
;
u8
human_readable
[
64
];
u8
human_readable
[
FW_VER_HUMAN_READABLE_SZ
];
__le32
ver
;
/* major/minor/API/serial */
__le32
ver
;
/* major/minor/API/serial */
__le32
build
;
__le32
build
;
__le64
ignore
;
__le64
ignore
;
...
...
drivers/net/wireless/iwlwifi/iwl-fw.h
View file @
5f4ef719
...
@@ -65,6 +65,8 @@
...
@@ -65,6 +65,8 @@
#include <linux/types.h>
#include <linux/types.h>
#include <net/mac80211.h>
#include <net/mac80211.h>
#include "iwl-fw-file.h"
/**
/**
* enum iwl_ucode_tlv_flag - ucode API flags
* enum iwl_ucode_tlv_flag - ucode API flags
* @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
* @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
...
@@ -117,11 +119,15 @@ enum iwl_ucode_tlv_flag {
...
@@ -117,11 +119,15 @@ enum iwl_ucode_tlv_flag {
/**
/**
* enum iwl_ucode_tlv_api - ucode api
* enum iwl_ucode_tlv_api - ucode api
* @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
* @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_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
{
enum
iwl_ucode_tlv_api
{
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID
=
BIT
(
0
),
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_CSA_FLOW
=
BIT
(
4
),
IWL_UCODE_TLV_API_DISABLE_STA_TX
=
BIT
(
5
),
};
};
/**
/**
...
@@ -178,6 +184,7 @@ enum iwl_ucode_sec {
...
@@ -178,6 +184,7 @@ enum iwl_ucode_sec {
struct
iwl_ucode_capabilities
{
struct
iwl_ucode_capabilities
{
u32
max_probe_length
;
u32
max_probe_length
;
u32
n_scan_channels
;
u32
standard_phy_calibration_size
;
u32
standard_phy_calibration_size
;
u32
flags
;
u32
flags
;
u32
api
[
IWL_API_ARRAY_SIZE
];
u32
api
[
IWL_API_ARRAY_SIZE
];
...
@@ -311,6 +318,7 @@ struct iwl_fw {
...
@@ -311,6 +318,7 @@ struct iwl_fw {
bool
mvm_fw
;
bool
mvm_fw
;
struct
ieee80211_cipher_scheme
cs
[
IWL_UCODE_MAX_CS
];
struct
ieee80211_cipher_scheme
cs
[
IWL_UCODE_MAX_CS
];
u8
human_readable
[
FW_VER_HUMAN_READABLE_SZ
];
};
};
#endif
/* __iwl_fw_h__ */
#endif
/* __iwl_fw_h__ */
drivers/net/wireless/iwlwifi/iwl-modparams.h
View file @
5f4ef719
...
@@ -103,6 +103,7 @@ enum iwl_disable_11n {
...
@@ -103,6 +103,7 @@ enum iwl_disable_11n {
* @power_level: power level, default = 1
* @power_level: power level, default = 1
* @debug_level: levels are IWL_DL_*
* @debug_level: levels are IWL_DL_*
* @ant_coupling: antenna coupling in dB, default = 0
* @ant_coupling: antenna coupling in dB, default = 0
* @fw_monitor: allow to use firmware monitor
*/
*/
struct
iwl_mod_params
{
struct
iwl_mod_params
{
int
sw_crypto
;
int
sw_crypto
;
...
@@ -120,6 +121,7 @@ struct iwl_mod_params {
...
@@ -120,6 +121,7 @@ struct iwl_mod_params {
int
ant_coupling
;
int
ant_coupling
;
char
*
nvm_file
;
char
*
nvm_file
;
bool
uapsd_disable
;
bool
uapsd_disable
;
bool
fw_monitor
;
};
};
#endif
/* #__iwl_modparams_h__ */
#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[] = {
...
@@ -174,7 +174,9 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
* @NVM_CHANNEL_IBSS: usable as an IBSS channel
* @NVM_CHANNEL_IBSS: usable as an IBSS channel
* @NVM_CHANNEL_ACTIVE: active scanning allowed
* @NVM_CHANNEL_ACTIVE: active scanning allowed
* @NVM_CHANNEL_RADAR: radar detection required
* @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_WIDE: 20 MHz channel okay (?)
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
* @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
* @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
...
@@ -185,7 +187,8 @@ enum iwl_nvm_channel_flags {
...
@@ -185,7 +187,8 @@ enum iwl_nvm_channel_flags {
NVM_CHANNEL_IBSS
=
BIT
(
1
),
NVM_CHANNEL_IBSS
=
BIT
(
1
),
NVM_CHANNEL_ACTIVE
=
BIT
(
3
),
NVM_CHANNEL_ACTIVE
=
BIT
(
3
),
NVM_CHANNEL_RADAR
=
BIT
(
4
),
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_WIDE
=
BIT
(
8
),
NVM_CHANNEL_40MHZ
=
BIT
(
9
),
NVM_CHANNEL_40MHZ
=
BIT
(
9
),
NVM_CHANNEL_80MHZ
=
BIT
(
10
),
NVM_CHANNEL_80MHZ
=
BIT
(
10
),
...
@@ -273,6 +276,16 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
...
@@ -273,6 +276,16 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
if
(
ch_flags
&
NVM_CHANNEL_RADAR
)
if
(
ch_flags
&
NVM_CHANNEL_RADAR
)
channel
->
flags
|=
IEEE80211_CHAN_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 */
/* Initialize regulatory-based run-time data */
/*
/*
...
@@ -282,7 +295,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
...
@@ -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
;
channel
->
max_power
=
DEFAULT_MAX_TX_POWER
;
is_5ghz
=
channel
->
band
==
IEEE80211_BAND_5GHZ
;
is_5ghz
=
channel
->
band
==
IEEE80211_BAND_5GHZ
;
IWL_DEBUG_EEPROM
(
dev
,
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
,
channel
->
hw_value
,
is_5ghz
?
"5.2"
:
"2.4"
,
is_5ghz
?
"5.2"
:
"2.4"
,
CHECK_AND_PRINT_I
(
VALID
),
CHECK_AND_PRINT_I
(
VALID
),
...
@@ -290,7 +303,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
...
@@ -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
(
ACTIVE
),
CHECK_AND_PRINT_I
(
RADAR
),
CHECK_AND_PRINT_I
(
RADAR
),
CHECK_AND_PRINT_I
(
WIDE
),
CHECK_AND_PRINT_I
(
WIDE
),
CHECK_AND_PRINT_I
(
DFS
),
CHECK_AND_PRINT_I
(
INDOOR_ONLY
),
CHECK_AND_PRINT_I
(
GO_CONCURRENT
),
ch_flags
,
ch_flags
,
channel
->
max_power
,
channel
->
max_power
,
((
ch_flags
&
NVM_CHANNEL_IBSS
)
&&
((
ch_flags
&
NVM_CHANNEL_IBSS
)
&&
...
@@ -462,7 +476,8 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
...
@@ -462,7 +476,8 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
data
->
hw_addr
[
5
]
=
hw_addr
[
4
];
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
,
struct
iwl_nvm_data
*
data
,
const
__le16
*
mac_override
,
const
__le16
*
mac_override
,
const
__le16
*
nvm_hw
)
const
__le16
*
nvm_hw
)
...
@@ -481,10 +496,14 @@ static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
...
@@ -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
[
4
]
=
hw_addr
[
5
];
data
->
hw_addr
[
5
]
=
hw_addr
[
4
];
data
->
hw_addr
[
5
]
=
hw_addr
[
4
];
if
(
is_valid_ether_addr
(
hw_addr
))
if
(
is_valid_ether_addr
(
data
->
hw_addr
))
return
;
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 */
/* take the MAC address from the OTP */
hw_addr
=
(
const
u8
*
)(
nvm_hw
+
HW_ADDR0_FAMILY_8000
);
hw_addr
=
(
const
u8
*
)(
nvm_hw
+
HW_ADDR0_FAMILY_8000
);
data
->
hw_addr
[
0
]
=
hw_addr
[
3
];
data
->
hw_addr
[
0
]
=
hw_addr
[
3
];
...
@@ -495,6 +514,10 @@ static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
...
@@ -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
);
hw_addr
=
(
const
u8
*
)(
nvm_hw
+
HW_ADDR1_FAMILY_8000
);
data
->
hw_addr
[
4
]
=
hw_addr
[
1
];
data
->
hw_addr
[
4
]
=
hw_addr
[
1
];
data
->
hw_addr
[
5
]
=
hw_addr
[
0
];
data
->
hw_addr
[
5
]
=
hw_addr
[
0
];
return
;
}
IWL_ERR_DEV
(
dev
,
"mac address is not found
\n
"
);
}
}
struct
iwl_nvm_data
*
struct
iwl_nvm_data
*
...
@@ -556,7 +579,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
...
@@ -556,7 +579,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
rx_chains
);
rx_chains
);
}
else
{
}
else
{
/* MAC address in family 8000 */
/* 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
,
iwl_init_sbands
(
dev
,
cfg
,
data
,
regulatory
,
sku
&
NVM_SKU_CAP_11AC_ENABLE
,
tx_chains
,
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 {
...
@@ -359,4 +359,10 @@ enum secure_load_status_reg {
#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
#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__ */
#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] = {
...
@@ -100,12 +100,13 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
#undef EVENT_PRIO_ANT
#undef EVENT_PRIO_ANT
#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
#define BT_ANTENNA_COUPLING_THRESHOLD (30)
#define BT_ANTENNA_COUPLING_THRESHOLD (30)
static
int
iwl_send_bt_prio_tbl
(
struct
iwl_mvm
*
mvm
)
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
,
return
iwl_mvm_send_cmd_pdu
(
mvm
,
BT_COEX_PRIO_TABLE
,
0
,
sizeof
(
struct
iwl_bt_coex_prio_tbl_cmd
),
sizeof
(
struct
iwl_bt_coex_prio_tbl_cmd
),
&
iwl_bt_prio_tbl
);
&
iwl_bt_prio_tbl
);
...
@@ -535,7 +536,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
...
@@ -535,7 +536,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
if
(
!
chanctx_conf
||
if
(
!
chanctx_conf
||
chanctx_conf
->
def
.
chan
->
band
!=
IEEE80211_BAND_2GHZ
)
{
chanctx_conf
->
def
.
chan
->
band
!=
IEEE80211_BAND_2GHZ
)
{
rcu_read_unlock
();
rcu_read_unlock
();
return
BT_COEX_
LOOSE
_LUT
;
return
BT_COEX_
INVALID
_LUT
;
}
}
ret
=
BT_COEX_TX_DIS_LUT
;
ret
=
BT_COEX_TX_DIS_LUT
;
...
@@ -578,6 +579,29 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
...
@@ -578,6 +579,29 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
return
-
ENOMEM
;
return
-
ENOMEM
;
cmd
.
data
[
0
]
=
bt_cmd
;
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
->
max_kill
=
5
;
bt_cmd
->
bt4_antenna_isolation_thr
=
BT_ANTENNA_COUPLING_THRESHOLD
;
bt_cmd
->
bt4_antenna_isolation_thr
=
BT_ANTENNA_COUPLING_THRESHOLD
;
bt_cmd
->
bt4_antenna_isolation
=
iwlwifi_mod_params
.
ant_coupling
;
bt_cmd
->
bt4_antenna_isolation
=
iwlwifi_mod_params
.
ant_coupling
;
...
@@ -642,6 +666,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
...
@@ -642,6 +666,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
bt_cmd
->
kill_cts_msk
=
bt_cmd
->
kill_cts_msk
=
cpu_to_le32
(
iwl_bt_cts_kill_msk
[
BT_KILL_MSK_DEFAULT
]);
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_notif
,
0
,
sizeof
(
mvm
->
last_bt_notif
));
memset
(
&
mvm
->
last_bt_ci_cmd
,
0
,
sizeof
(
mvm
->
last_bt_ci_cmd
));
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,
...
@@ -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
.
last_bt_coex_event
=
rssi
;
mvmvif
->
bf_data
.
bt_coex_max_thold
=
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
=
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 */
/* must be called under rcu_read_lock */
...
@@ -919,7 +944,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
...
@@ -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 the RSSI isn't valid, fake it is very low */
if
(
!
ave_rssi
)
if
(
!
ave_rssi
)
ave_rssi
=
-
100
;
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
))
if
(
iwl_mvm_bt_coex_reduced_txp
(
mvm
,
mvmvif
->
ap_sta_id
,
true
))
IWL_ERR
(
mvm
,
"Couldn't send BT_CONFIG cmd
\n
"
);
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,
...
@@ -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,
* the iteration, if one interface's rssi isn't good enough,
* bt_kill_msk will be set to default values.
* 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
))
if
(
iwl_mvm_bt_coex_reduced_txp
(
mvm
,
mvmvif
->
ap_sta_id
,
false
))
IWL_ERR
(
mvm
,
"Couldn't send BT_CONFIG cmd
\n
"
);
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)
...
@@ -955,6 +980,10 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
struct
iwl_bt_coex_ci_cmd
cmd
=
{};
struct
iwl_bt_coex_ci_cmd
cmd
=
{};
u8
ci_bw_idx
;
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
();
rcu_read_lock
();
ieee80211_iterate_active_interfaces_atomic
(
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
...
@@ -1121,6 +1150,10 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...
@@ -1121,6 +1150,10 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
lockdep_assert_held
(
&
mvm
->
mutex
);
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
* Rssi update while not associated - can happen since the statistics
* are handled asynchronously
* are handled asynchronously
...
@@ -1177,9 +1210,12 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
...
@@ -1177,9 +1210,12 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
BT_HIGH_TRAFFIC
)
BT_HIGH_TRAFFIC
)
return
LINK_QUAL_AGG_TIME_LIMIT_DEF
;
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
);
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
;
return
LINK_QUAL_AGG_TIME_LIMIT_DEF
;
/* tight coex, high bt traffic, reduce AGG time limit */
/* 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,
...
@@ -1190,18 +1226,29 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
struct
ieee80211_sta
*
sta
)
struct
ieee80211_sta
*
sta
)
{
{
struct
iwl_mvm_sta
*
mvmsta
=
iwl_mvm_sta_from_mac80211
(
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
)
<
if
(
le32_to_cpu
(
mvm
->
last_bt_notif
.
bt_activity_grading
)
<
BT_HIGH_TRAFFIC
)
BT_HIGH_TRAFFIC
)
return
true
;
return
true
;
/*
/*
* In Tight, BT can't Rx while we Tx, so use both antennas since BT is
* In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas
* already killed.
* since BT is already killed.
* In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while we
* In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while
* Tx.
* 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
,
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,
...
@@ -1274,6 +1321,10 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
lockdep_assert_held
(
&
mvm
->
mutex
);
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
)
if
(
ant_isolation
==
mvm
->
last_ant_isol
)
return
0
;
return
0
;
...
...
drivers/net/wireless/iwlwifi/mvm/constants.h
View file @
5f4ef719
...
@@ -79,6 +79,8 @@
...
@@ -79,6 +79,8 @@
#define IWL_MVM_PS_SNOOZE_WINDOW 50
#define IWL_MVM_PS_SNOOZE_WINDOW 50
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
#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_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING 1
#define IWL_MVM_BT_COEX_CORUNNING 1
#define IWL_MVM_BT_COEX_MPLUT 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,
...
@@ -455,6 +455,43 @@ iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf,
return
count
;
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) \
#define PRINT_STATS_LE32(_str, _val) \
pos += scnprintf(buf + pos, bufsz - pos, \
pos += scnprintf(buf + pos, bufsz - pos, \
fmt_table, _str, \
fmt_table, _str, \
...
@@ -1101,6 +1138,7 @@ MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
...
@@ -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_restart
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_nmi
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_nmi
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
bt_tx_prio
,
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
(
scan_ant_rxchain
,
8
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
d0i3_refs
,
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)
...
@@ -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_restart
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_nmi
,
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_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
,
MVM_DEBUGFS_ADD_FILE
(
scan_ant_rxchain
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
S_IWUSR
|
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
prph_reg
,
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 @@
...
@@ -76,6 +76,9 @@
* @BT_COEX_2W:
* @BT_COEX_2W:
* @BT_COEX_3W:
* @BT_COEX_3W:
* @BT_COEX_NW:
* @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_SYNC2SCO:
* @BT_COEX_CORUNNING:
* @BT_COEX_CORUNNING:
* @BT_COEX_MPLUT:
* @BT_COEX_MPLUT:
...
@@ -89,6 +92,9 @@ enum iwl_bt_coex_flags {
...
@@ -89,6 +92,9 @@ enum iwl_bt_coex_flags {
BT_COEX_2W
=
0x1
<<
BT_COEX_MODE_POS
,
BT_COEX_2W
=
0x1
<<
BT_COEX_MODE_POS
,
BT_COEX_3W
=
0x2
<<
BT_COEX_MODE_POS
,
BT_COEX_3W
=
0x2
<<
BT_COEX_MODE_POS
,
BT_COEX_NW
=
0x3
<<
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_SYNC2SCO
=
BIT
(
7
),
BT_COEX_CORUNNING
=
BIT
(
8
),
BT_COEX_CORUNNING
=
BIT
(
8
),
BT_COEX_MPLUT
=
BIT
(
9
),
BT_COEX_MPLUT
=
BIT
(
9
),
...
@@ -299,6 +305,7 @@ enum iwl_bt_activity_grading {
...
@@ -299,6 +305,7 @@ enum iwl_bt_activity_grading {
* @bt_traffic_load: load of BT traffic
* @bt_traffic_load: load of BT traffic
* @bt_agg_traffic_load: aggregated load of BT traffic
* @bt_agg_traffic_load: aggregated load of BT traffic
* @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
* @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
* @primary_ch_lut: LUT used for primary channel
* @secondary_ch_lut: LUT used for secondary channel
* @secondary_ch_lut: LUT used for secondary channel
* @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
* @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
...
@@ -311,7 +318,8 @@ struct iwl_bt_coex_profile_notif {
...
@@ -311,7 +318,8 @@ struct iwl_bt_coex_profile_notif {
u8
bt_traffic_load
;
u8
bt_traffic_load
;
u8
bt_agg_traffic_load
;
u8
bt_agg_traffic_load
;
u8
bt_ci_compliance
;
u8
bt_ci_compliance
;
u8
reserved
[
3
];
u8
ttc_enabled
;
__le16
reserved
;
__le32
primary_ch_lut
;
__le32
primary_ch_lut
;
__le32
secondary_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 {
...
@@ -336,7 +336,7 @@ struct iwl_beacon_filter_cmd {
#define IWL_BF_DEBUG_FLAG_D0I3 0
#define IWL_BF_DEBUG_FLAG_D0I3 0
#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
#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_MAX 1024
#define IWL_BF_ESCAPE_TIMER_MIN 0
#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 {
...
@@ -169,19 +169,13 @@ enum iwl_scan_type {
SCAN_TYPE_DISCOVERY_FORCED
=
6
,
SCAN_TYPE_DISCOVERY_FORCED
=
6
,
};
/* SCAN_ACTIVITY_TYPE_E_VER_1 */
};
/* 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
* struct iwl_scan_cmd - scan request command
* ( SCAN_REQUEST_CMD = 0x80 )
* ( SCAN_REQUEST_CMD = 0x80 )
* @len: command length in bytes
* @len: command length in bytes
* @scan_flags: scan flags from SCAN_FLAGS_*
* @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_time: in msecs, dwell this time for active scan on quiet channels
* @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
* @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
* this number of packets were received (typically 1)
* this number of packets were received (typically 1)
...
@@ -345,7 +339,7 @@ struct iwl_scan_results_notif {
...
@@ -345,7 +339,7 @@ struct iwl_scan_results_notif {
* @last_channel: last channel that was scanned
* @last_channel: last channel that was scanned
* @tsf_low: TSF timer (lower half) in usecs
* @tsf_low: TSF timer (lower half) in usecs
* @tsf_high: TSF timer (higher 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
{
struct
iwl_scan_complete_notif
{
u8
scanned_channels
;
u8
scanned_channels
;
...
@@ -354,11 +348,10 @@ struct iwl_scan_complete_notif {
...
@@ -354,11 +348,10 @@ struct iwl_scan_complete_notif {
u8
last_channel
;
u8
last_channel
;
__le32
tsf_low
;
__le32
tsf_low
;
__le32
tsf_high
;
__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 */
}
__packed
;
/* SCAN_COMPLETE_NTF_API_S_VER_2 */
/* scan offload */
/* scan offload */
#define IWL_MAX_SCAN_CHANNELS 40
#define IWL_SCAN_MAX_BLACKLIST_LEN 64
#define IWL_SCAN_MAX_BLACKLIST_LEN 64
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
#define IWL_SCAN_MAX_PROFILES 11
#define IWL_SCAN_MAX_PROFILES 11
...
@@ -423,36 +416,24 @@ enum iwl_scan_offload_channel_flags {
...
@@ -423,36 +416,24 @@ enum iwl_scan_offload_channel_flags {
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL
=
BIT
(
25
),
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL
=
BIT
(
25
),
};
};
/**
/* channel configuration for struct iwl_scan_offload_cfg. Each channels needs:
* iwl_scan_channel_cfg - SCAN_CHANNEL_CFG_S
* __le32 type: bitmap; bits 1-20 are for directed scan to i'th ssid and
* @type: bitmap - see enum iwl_scan_offload_channel_flags.
* see enum iwl_scan_offload_channel_flags.
* 0: passive (0) or active (1) scan.
* __le16 channel_number: channel number 1-13 etc.
* 1-20: directed scan to i'th ssid.
* __le16 iter_count: repetition count for the channel.
* 22: channel width configuation - 1 for narrow.
* __le32 iter_interval: interval between two innteration on one channel.
* 24: full scan.
* u8 active_dwell.
* 25: partial scan.
* u8 passive_dwell.
* @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.
*/
*/
struct
iwl_scan_channel_cfg
{
#define IWL_SCAN_CHAN_SIZE 14
__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
;
/**
/**
* iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S
* iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S
* @scan_cmd: scan command fixed part
* @scan_cmd: scan command fixed part
* @channel_cfg: scan channel configuration
* @data: scan channel configuration and probe request frames
* @data: probe request frames (one per band)
*/
*/
struct
iwl_scan_offload_cfg
{
struct
iwl_scan_offload_cfg
{
struct
iwl_scan_offload_cmd
scan_cmd
;
struct
iwl_scan_offload_cmd
scan_cmd
;
struct
iwl_scan_channel_cfg
channel_cfg
;
u8
data
[
0
];
u8
data
[
0
];
}
__packed
;
}
__packed
;
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
View file @
5f4ef719
...
@@ -67,7 +67,7 @@
...
@@ -67,7 +67,7 @@
* enum iwl_sta_flags - flags for the ADD_STA host command
* enum iwl_sta_flags - flags for the ADD_STA host command
* @STA_FLG_REDUCED_TX_PWR_CTRL:
* @STA_FLG_REDUCED_TX_PWR_CTRL:
* @STA_FLG_REDUCED_TX_PWR_DATA:
* @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_PS: set if STA is in Power Save
* @STA_FLG_INVALID: set if STA is invalid
* @STA_FLG_INVALID: set if STA is invalid
* @STA_FLG_DLP_EN: Direct Link Protocol is enabled
* @STA_FLG_DLP_EN: Direct Link Protocol is enabled
...
@@ -91,10 +91,7 @@ enum iwl_sta_flags {
...
@@ -91,10 +91,7 @@ enum iwl_sta_flags {
STA_FLG_REDUCED_TX_PWR_CTRL
=
BIT
(
3
),
STA_FLG_REDUCED_TX_PWR_CTRL
=
BIT
(
3
),
STA_FLG_REDUCED_TX_PWR_DATA
=
BIT
(
6
),
STA_FLG_REDUCED_TX_PWR_DATA
=
BIT
(
6
),
STA_FLG_FLG_ANT_A
=
(
1
<<
4
),
STA_FLG_DISABLE_TX
=
BIT
(
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_PS
=
BIT
(
8
),
STA_FLG_PS
=
BIT
(
8
),
STA_FLG_DRAIN_FLOW
=
BIT
(
12
),
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 {
...
@@ -548,6 +548,20 @@ struct iwl_beacon_notif {
__le32
ibss_mgr_status
;
__le32
ibss_mgr_status
;
}
__packed
;
}
__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
* enum iwl_dump_control - dump (flush) control flags
* @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
* @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,
...
@@ -904,7 +904,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
struct
iwl_mac_beacon_cmd
beacon_cmd
=
{};
struct
iwl_mac_beacon_cmd
beacon_cmd
=
{};
struct
ieee80211_tx_info
*
info
;
struct
ieee80211_tx_info
*
info
;
u32
beacon_skb_len
;
u32
beacon_skb_len
;
u32
rate
;
u32
rate
,
tx_flags
;
if
(
WARN_ON
(
!
beacon
))
if
(
WARN_ON
(
!
beacon
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -914,14 +914,17 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
...
@@ -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.
/* TODO: for now the beacon template id is set to be the mac context id.
* Might be better to handle it as another resource ... */
* Might be better to handle it as another resource ... */
beacon_cmd
.
template_id
=
cpu_to_le32
((
u32
)
mvmvif
->
id
);
beacon_cmd
.
template_id
=
cpu_to_le32
((
u32
)
mvmvif
->
id
);
info
=
IEEE80211_SKB_CB
(
beacon
);
/* Set up TX command fields */
/* Set up TX command fields */
beacon_cmd
.
tx
.
len
=
cpu_to_le16
((
u16
)
beacon_skb_len
);
beacon_cmd
.
tx
.
len
=
cpu_to_le16
((
u16
)
beacon_skb_len
);
beacon_cmd
.
tx
.
sta_id
=
mvmvif
->
bcast_sta
.
sta_id
;
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
.
life_time
=
cpu_to_le32
(
TX_CMD_LIFE_TIME_INFINITE
);
beacon_cmd
.
tx
.
tx_flags
=
cpu_to_le32
(
TX_CMD_FLG_SEQ_CTL
|
tx_flags
=
TX_CMD_FLG_SEQ_CTL
|
TX_CMD_FLG_TSF
;
TX_CMD_FLG_BT_DIS
|
tx_flags
|=
TX_CMD_FLG_TSF
);
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
=
mvm
->
mgmt_last_antenna_idx
=
iwl_mvm_next_antenna
(
mvm
,
mvm
->
fw
->
valid_tx_ant
,
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,
...
@@ -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
)
<<
cpu_to_le32
(
BIT
(
mvm
->
mgmt_last_antenna_idx
)
<<
RATE_MCS_ANT_POS
);
RATE_MCS_ANT_POS
);
info
=
IEEE80211_SKB_CB
(
beacon
);
if
(
info
->
band
==
IEEE80211_BAND_5GHZ
||
vif
->
p2p
)
{
if
(
info
->
band
==
IEEE80211_BAND_5GHZ
||
vif
->
p2p
)
{
rate
=
IWL_FIRST_OFDM_RATE
;
rate
=
IWL_FIRST_OFDM_RATE
;
}
else
{
}
else
{
...
@@ -1205,19 +1206,31 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
...
@@ -1205,19 +1206,31 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
struct
iwl_device_cmd
*
cmd
)
struct
iwl_device_cmd
*
cmd
)
{
{
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_beacon_notif
*
beacon
=
(
void
*
)
pkt
->
data
;
struct
iwl_mvm_tx_resp
*
beacon_notify_hdr
;
u16
status
__maybe_unused
=
u64
tsf
;
le16_to_cpu
(
beacon
->
beacon_notify_hdr
.
status
.
status
);
u32
rate
__maybe_unused
=
le32_to_cpu
(
beacon
->
beacon_notify_hdr
.
initial_rate
);
lockdep_assert_held
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
IWL_DEBUG_RX
(
mvm
,
"beacon status %#x retries:%d tsf:0x%16llX rate:%d
\n
"
,
if
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_CAPA_EXTENDED_BEACON
)
{
status
&
TX_STATUS_MSK
,
struct
iwl_extended_beacon_notif
*
beacon
=
(
void
*
)
pkt
->
data
;
beacon
->
beacon_notify_hdr
.
failure_frame
,
le64_to_cpu
(
beacon
->
tsf
),
beacon_notify_hdr
=
&
beacon
->
beacon_notify_hdr
;
rate
);
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
(
unlikely
(
mvm
->
csa_vif
&&
mvm
->
csa_vif
->
csa_active
))
{
if
(
!
ieee80211_csa_is_complete
(
mvm
->
csa_vif
))
{
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)
...
@@ -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
->
max_sched_scan_ie_len
=
SCAN_OFFLOAD_PROBE_REQ_SIZE
-
24
-
2
;
hw
->
wiphy
->
features
|=
NL80211_FEATURE_P2P_GO_CTWIN
|
hw
->
wiphy
->
features
|=
NL80211_FEATURE_P2P_GO_CTWIN
|
NL80211_FEATURE_LOW_PRIORITY_SCAN
|
NL80211_FEATURE_P2P_GO_OPPPS
;
NL80211_FEATURE_P2P_GO_OPPPS
;
mvm
->
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
;
mvm
->
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
;
...
@@ -688,6 +689,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
...
@@ -688,6 +689,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
iwl_mvm_restart_cleanup
(
mvm
);
iwl_mvm_restart_cleanup
(
mvm
);
ret
=
iwl_mvm_up
(
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
);
mutex_unlock
(
&
mvm
->
mutex
);
return
ret
;
return
ret
;
...
@@ -1464,6 +1475,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
...
@@ -1464,6 +1475,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
mvmvif
->
ap_ibss_active
=
false
;
mvmvif
->
ap_ibss_active
=
false
;
mvm
->
ap_last_beacon_gp2
=
0
;
iwl_mvm_bt_coex_vif_change
(
mvm
);
iwl_mvm_bt_coex_vif_change
(
mvm
);
...
@@ -1543,7 +1555,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
...
@@ -1543,7 +1555,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
struct
cfg80211_scan_request
*
req
=
&
hw_req
->
req
;
struct
cfg80211_scan_request
*
req
=
&
hw_req
->
req
;
int
ret
;
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
;
return
-
EINVAL
;
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
View file @
5f4ef719
...
@@ -235,6 +235,15 @@ enum iwl_mvm_ref_type {
...
@@ -235,6 +235,15 @@ enum iwl_mvm_ref_type {
IWL_MVM_REF_COUNT
,
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
* struct iwl_mvm_vif_bf_data - beacon filtering related data
* @bf_enabled: indicates if beacon filtering is enabled
* @bf_enabled: indicates if beacon filtering is enabled
...
@@ -629,6 +638,7 @@ struct iwl_mvm {
...
@@ -629,6 +638,7 @@ struct iwl_mvm {
u32
last_ant_isol
;
u32
last_ant_isol
;
u8
last_corun_lut
;
u8
last_corun_lut
;
u8
bt_tx_prio
;
u8
bt_tx_prio
;
enum
iwl_bt_force_ant_mode
bt_force_ant_mode
;
/* Thermal Throttling and CTkill */
/* Thermal Throttling and CTkill */
struct
iwl_mvm_tt_mgmt
thermal_throttle
;
struct
iwl_mvm_tt_mgmt
thermal_throttle
;
...
@@ -648,6 +658,9 @@ struct iwl_mvm {
...
@@ -648,6 +658,9 @@ struct iwl_mvm {
bool
ps_disabled
;
bool
ps_disabled
;
struct
ieee80211_vif
*
csa_vif
;
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 */
/* Extract MVM priv from op_mode and _hw */
...
@@ -963,6 +976,7 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
...
@@ -963,6 +976,7 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
struct
ieee80211_sta
*
sta
);
struct
ieee80211_sta
*
sta
);
bool
iwl_mvm_bt_coex_is_mimo_allowed
(
struct
iwl_mvm
*
mvm
,
bool
iwl_mvm_bt_coex_is_mimo_allowed
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
);
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
,
bool
iwl_mvm_bt_coex_is_tpc_allowed
(
struct
iwl_mvm
*
mvm
,
enum
ieee80211_band
band
);
enum
ieee80211_band
band
);
u8
iwl_mvm_bt_coex_tx_prio
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_hdr
*
hdr
,
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 @@
...
@@ -69,7 +69,9 @@
/* Default NVM size to read */
/* Default NVM size to read */
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
#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_WRITE_OPCODE 1
#define NVM_READ_OPCODE 0
#define NVM_READ_OPCODE 0
...
@@ -219,7 +221,7 @@ static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
...
@@ -219,7 +221,7 @@ static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
* without overflowing, so no check is needed.
* without overflowing, so no check is needed.
*/
*/
static
int
iwl_nvm_read_section
(
struct
iwl_mvm
*
mvm
,
u16
section
,
static
int
iwl_nvm_read_section
(
struct
iwl_mvm
*
mvm
,
u16
section
,
u8
*
data
)
u8
*
data
,
u32
size_read
)
{
{
u16
length
,
offset
=
0
;
u16
length
,
offset
=
0
;
int
ret
;
int
ret
;
...
@@ -231,6 +233,13 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
...
@@ -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) */
/* Read the NVM until exhausted (reading less than requested) */
while
(
ret
==
length
)
{
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
);
ret
=
iwl_nvm_read_chunk
(
mvm
,
section
,
offset
,
length
,
data
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
...
@@ -326,6 +335,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
...
@@ -326,6 +335,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
u8
data
[];
u8
data
[];
}
*
file_sec
;
}
*
file_sec
;
const
u8
*
eof
,
*
temp
;
const
u8
*
eof
,
*
temp
;
int
max_section_size
;
#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
#define NVM_WORD2_ID(x) (x >> 12)
#define NVM_WORD2_ID(x) (x >> 12)
...
@@ -334,6 +344,14 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
...
@@ -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
"
);
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
* Obtain NVM image via request_firmware. Since we already used
* request_firmware_nowait() for the firmware binary load and only
* 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)
...
@@ -392,7 +410,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
le16_to_cpu
(
file_sec
->
word1
));
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
"
,
IWL_ERR
(
mvm
,
"ERROR - section too large (%d)
\n
"
,
section_size
);
section_size
);
ret
=
-
EINVAL
;
ret
=
-
EINVAL
;
...
@@ -459,6 +477,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
...
@@ -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
iwl_nvm_init
(
struct
iwl_mvm
*
mvm
,
bool
read_nvm_from_nic
)
{
{
int
ret
,
section
;
int
ret
,
section
;
u32
size_read
=
0
;
u8
*
nvm_buffer
,
*
temp
;
u8
*
nvm_buffer
,
*
temp
;
if
(
WARN_ON_ONCE
(
mvm
->
cfg
->
nvm_hw_section_num
>=
NVM_MAX_NUM_SECTIONS
))
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)
...
@@ -475,9 +494,11 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
return
-
ENOMEM
;
return
-
ENOMEM
;
for
(
section
=
0
;
section
<
NVM_MAX_NUM_SECTIONS
;
section
++
)
{
for
(
section
=
0
;
section
<
NVM_MAX_NUM_SECTIONS
;
section
++
)
{
/* we override the constness for initial read */
/* 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
)
if
(
ret
<
0
)
continue
;
continue
;
size_read
+=
ret
;
temp
=
kmemdup
(
nvm_buffer
,
ret
,
GFP_KERNEL
);
temp
=
kmemdup
(
nvm_buffer
,
ret
,
GFP_KERNEL
);
if
(
!
temp
)
{
if
(
!
temp
)
{
ret
=
-
ENOMEM
;
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,
...
@@ -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
)
+
scan_size
=
sizeof
(
struct
iwl_scan_cmd
)
+
mvm
->
fw
->
ucode_capa
.
max_probe_length
+
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
);
mvm
->
scan_cmd
=
kmalloc
(
scan_size
,
GFP_KERNEL
);
if
(
!
mvm
->
scan_cmd
)
if
(
!
mvm
->
scan_cmd
)
goto
out_free
;
goto
out_free
;
...
@@ -826,6 +827,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
...
@@ -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_file
*
dump_file
;
struct
iwl_fw_error_dump_data
*
dump_data
;
struct
iwl_fw_error_dump_data
*
dump_data
;
struct
iwl_fw_error_dump_info
*
dump_info
;
u32
file_len
;
u32
file_len
;
u32
trans_len
;
u32
trans_len
;
...
@@ -834,10 +836,11 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
...
@@ -834,10 +836,11 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
if
(
mvm
->
fw_error_dump
)
if
(
mvm
->
fw_error_dump
)
return
;
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
+
mvm
->
fw_error_rxf_len
+
sizeof
(
*
dump_file
)
+
sizeof
(
*
dump_info
);
sizeof
(
*
dump_data
)
*
2
;
trans_len
=
iwl_trans_dump_data
(
mvm
->
trans
,
NULL
,
0
);
trans_len
=
iwl_trans_dump_data
(
mvm
->
trans
,
NULL
,
0
);
if
(
trans_len
)
if
(
trans_len
)
...
@@ -852,11 +855,27 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
...
@@ -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
->
barker
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_BARKER
);
dump_file
->
file_len
=
cpu_to_le32
(
file_len
);
dump_file
->
file_len
=
cpu_to_le32
(
file_len
);
dump_data
=
(
void
*
)
dump_file
->
data
;
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
->
type
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_RXF
);
dump_data
->
len
=
cpu_to_le32
(
mvm
->
fw_error_rxf_len
);
dump_data
->
len
=
cpu_to_le32
(
mvm
->
fw_error_rxf_len
);
memcpy
(
dump_data
->
data
,
mvm
->
fw_error_rxf
,
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
->
type
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_SRAM
);
dump_data
->
len
=
cpu_to_le32
(
mvm
->
fw_error_sram_len
);
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)
...
@@ -876,7 +895,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
mvm
->
fw_error_sram_len
=
0
;
mvm
->
fw_error_sram_len
=
0
;
if
(
trans_len
)
{
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
,
u32
real_trans_len
=
iwl_trans_dump_data
(
mvm
->
trans
,
buf
,
trans_len
);
trans_len
);
dump_data
=
(
void
*
)((
u8
*
)
buf
+
real_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,
...
@@ -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
,
static
void
iwl_mvm_scan_calc_params
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_vif
*
vif
,
int
n_ssids
,
int
n_ssids
,
u32
flags
,
struct
iwl_mvm_scan_params
*
params
)
struct
iwl_mvm_scan_params
*
params
)
{
{
bool
global_bound
=
false
;
bool
global_bound
=
false
;
...
@@ -297,6 +297,9 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
...
@@ -297,6 +297,9 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
params
->
max_out_time
=
250
;
params
->
max_out_time
=
250
;
}
}
if
(
flags
&
NL80211_SCAN_FLAG_LOW_PRIORITY
)
params
->
max_out_time
=
200
;
not_bound:
not_bound:
for
(
band
=
IEEE80211_BAND_2GHZ
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
for
(
band
=
IEEE80211_BAND_2GHZ
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
...
@@ -333,16 +336,14 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
...
@@ -333,16 +336,14 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
IWL_DEBUG_SCAN
(
mvm
,
"Handling mac80211 scan request
\n
"
);
IWL_DEBUG_SCAN
(
mvm
,
"Handling mac80211 scan request
\n
"
);
mvm
->
scan_status
=
IWL_MVM_SCAN_OS
;
mvm
->
scan_status
=
IWL_MVM_SCAN_OS
;
memset
(
cmd
,
0
,
sizeof
(
struct
iwl_scan_cmd
)
+
memset
(
cmd
,
0
,
ksize
(
cmd
));
mvm
->
fw
->
ucode_capa
.
max_probe_length
+
(
MAX_NUM_SCAN_CHANNELS
*
sizeof
(
struct
iwl_scan_channel
)));
cmd
->
channel_count
=
(
u8
)
req
->
n_channels
;
cmd
->
channel_count
=
(
u8
)
req
->
n_channels
;
cmd
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
cmd
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
cmd
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
cmd
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
cmd
->
rxchain_sel_flags
=
iwl_mvm_scan_rx_chain
(
mvm
);
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
->
max_out_time
=
cpu_to_le32
(
params
.
max_out_time
);
cmd
->
suspend_time
=
cpu_to_le32
(
params
.
suspend_time
);
cmd
->
suspend_time
=
cpu_to_le32
(
params
.
suspend_time
);
if
(
params
.
passive_fragmented
)
if
(
params
.
passive_fragmented
)
...
@@ -597,9 +598,7 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
...
@@ -597,9 +598,7 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
struct
iwl_scan_offload_cmd
*
scan
,
struct
iwl_scan_offload_cmd
*
scan
,
struct
iwl_mvm_scan_params
*
params
)
struct
iwl_mvm_scan_params
*
params
)
{
{
scan
->
channel_count
=
scan
->
channel_count
=
req
->
n_channels
;
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
+
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
scan
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
scan
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
scan
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
scan
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
scan
->
good_CRC_th
=
IWL_GOOD_CRC_TH_DEFAULT
;
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,
...
@@ -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
,
static
void
iwl_build_channel_cfg
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
,
struct
cfg80211_sched_scan_request
*
req
,
struct
iwl_scan_channel_cfg
*
channels
,
u8
*
channels_buffer
,
enum
ieee80211_band
band
,
enum
ieee80211_band
band
,
int
*
head
,
int
*
tail
,
int
*
head
,
u32
ssid_bitmap
,
u32
ssid_bitmap
,
struct
iwl_mvm_scan_params
*
params
)
struct
iwl_mvm_scan_params
*
params
)
{
{
struct
ieee80211_supported_band
*
s_band
;
u32
n_channels
=
mvm
->
fw
->
ucode_capa
.
n_scan_channels
;
int
n_channels
=
req
->
n_channels
;
__le32
*
type
=
(
__le32
*
)
channels_buffer
;
int
i
,
j
,
index
=
0
;
__le16
*
channel_number
=
(
__le16
*
)(
type
+
n_channels
);
bool
partial
;
__le16
*
iter_count
=
channel_number
+
n_channels
;
__le32
*
iter_interval
=
(
__le32
*
)(
iter_count
+
n_channels
);
/*
u8
*
active_dwell
=
(
u8
*
)(
iter_interval
+
n_channels
);
* We have to configure all supported channels, even if we don't want to
u8
*
passive_dwell
=
active_dwell
+
n_channels
;
* scan on them, but we have to send channels in the order that we want
int
i
,
index
=
0
;
* to scan. So add requested channels to head of the list and others to
* the end.
for
(
i
=
0
;
i
<
req
->
n_channels
;
i
++
)
{
*/
struct
ieee80211_channel
*
chan
=
req
->
channels
[
i
];
s_band
=
&
mvm
->
nvm_data
->
bands
[
band
];
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
;
index
=
*
head
;
(
*
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
);
channel_number
[
index
]
=
cpu_to_le16
(
chan
->
hw_value
);
channels
->
iter_interval
[
index
]
=
0
;
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
))
if
(
!
(
chan
->
flags
&
IEEE80211_CHAN_NO_IR
))
channels
->
type
[
index
]
|=
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE
);
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE
);
channels
->
type
[
index
]
|=
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_FULL
|
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_FULL
);
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL
);
if
(
partial
)
channels
->
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL
);
if
(
s_band
->
channels
[
i
].
flags
&
IEEE80211_CHAN_NO_HT40
)
if
(
chan
->
flags
&
IEEE80211_CHAN_NO_HT40
)
channels
->
type
[
index
]
|=
type
[
index
]
|=
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_NARROW
);
cpu_to_le32
(
IWL_SCAN_OFFLOAD_CHANNEL_NARROW
);
/* scan for all SSIDs from req->ssids */
/* 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,
...
@@ -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_2ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
;
int
band_5ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
int
band_5ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
int
head
=
0
;
int
head
=
0
;
int
tail
=
band_2ghz
+
band_5ghz
-
1
;
u32
ssid_bitmap
;
u32
ssid_bitmap
;
int
cmd_len
;
int
cmd_len
;
int
ret
;
int
ret
;
u8
*
probes
;
struct
iwl_scan_offload_cfg
*
scan_cfg
;
struct
iwl_scan_offload_cfg
*
scan_cfg
;
struct
iwl_host_cmd
cmd
=
{
struct
iwl_host_cmd
cmd
=
{
...
@@ -763,13 +744,17 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
...
@@ -763,13 +744,17 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
lockdep_assert_held
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
cmd_len
=
sizeof
(
struct
iwl_scan_offload_cfg
)
+
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
;
2
*
SCAN_OFFLOAD_PROBE_REQ_SIZE
;
scan_cfg
=
kzalloc
(
cmd_len
,
GFP_KERNEL
);
scan_cfg
=
kzalloc
(
cmd_len
,
GFP_KERNEL
);
if
(
!
scan_cfg
)
if
(
!
scan_cfg
)
return
-
ENOMEM
;
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
);
iwl_build_scan_cmd
(
mvm
,
vif
,
req
,
&
scan_cfg
->
scan_cmd
,
&
params
);
scan_cfg
->
scan_cmd
.
len
=
cpu_to_le16
(
cmd_len
);
scan_cfg
->
scan_cmd
.
len
=
cpu_to_le16
(
cmd_len
);
...
@@ -779,19 +764,19 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
...
@@ -779,19 +764,19 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
IEEE80211_BAND_2GHZ
,
IEEE80211_BAND_2GHZ
,
&
scan_cfg
->
scan_cmd
.
tx_cmd
[
0
],
&
scan_cfg
->
scan_cmd
.
tx_cmd
[
0
],
scan_cfg
->
data
);
probes
);
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
iwl_build_channel_cfg
(
mvm
,
req
,
scan_cfg
->
data
,
IEEE80211_BAND_2GHZ
,
&
head
,
&
tail
,
IEEE80211_BAND_2GHZ
,
&
head
,
ssid_bitmap
,
&
params
);
ssid_bitmap
,
&
params
);
}
}
if
(
band_5ghz
)
{
if
(
band_5ghz
)
{
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
IEEE80211_BAND_5GHZ
,
IEEE80211_BAND_5GHZ
,
&
scan_cfg
->
scan_cmd
.
tx_cmd
[
1
],
&
scan_cfg
->
scan_cmd
.
tx_cmd
[
1
],
scan_cfg
->
data
+
probes
+
SCAN_OFFLOAD_PROBE_REQ_SIZE
);
SCAN_OFFLOAD_PROBE_REQ_SIZE
);
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
iwl_build_channel_cfg
(
mvm
,
req
,
scan_cfg
->
data
,
IEEE80211_BAND_5GHZ
,
&
head
,
&
tail
,
IEEE80211_BAND_5GHZ
,
&
head
,
ssid_bitmap
,
&
params
);
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,
...
@@ -1448,3 +1448,23 @@ int iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
return
0
;
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,
...
@@ -404,5 +404,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
bool
agg
);
bool
agg
);
int
iwl_mvm_drain_sta
(
struct
iwl_mvm
*
mvm
,
struct
iwl_mvm_sta
*
mvmsta
,
int
iwl_mvm_drain_sta
(
struct
iwl_mvm
*
mvm
,
struct
iwl_mvm_sta
*
mvmsta
,
bool
drain
);
bool
drain
);
void
iwl_mvm_sta_modify_disable_tx
(
struct
iwl_mvm
*
mvm
,
struct
iwl_mvm_sta
*
mvmsta
,
bool
disable
);
#endif
/* __sta_h__ */
#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,
...
@@ -205,7 +205,13 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
mvm
->
mgmt_last_antenna_idx
=
mvm
->
mgmt_last_antenna_idx
=
iwl_mvm_next_antenna
(
mvm
,
mvm
->
fw
->
valid_tx_ant
,
iwl_mvm_next_antenna
(
mvm
,
mvm
->
fw
->
valid_tx_ant
,
mvm
->
mgmt_last_antenna_idx
);
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 */
/* Set CCK flag as needed */
if
((
rate_idx
>=
IWL_FIRST_CCK_RATE
)
&&
(
rate_idx
<=
IWL_LAST_CCK_RATE
))
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)
...
@@ -260,6 +260,9 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
* @wd_timeout: queue watchdog timeout (jiffies)
* @wd_timeout: queue watchdog timeout (jiffies)
* @reg_lock: protect hw register access
* @reg_lock: protect hw register access
* @cmd_in_flight: true when we have a host command in flight
* @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_trans_pcie
{
struct
iwl_rxq
rxq
;
struct
iwl_rxq
rxq
;
...
@@ -312,6 +315,10 @@ struct iwl_trans_pcie {
...
@@ -312,6 +315,10 @@ struct iwl_trans_pcie {
/*protect hw register */
/*protect hw register */
spinlock_t
reg_lock
;
spinlock_t
reg_lock
;
bool
cmd_in_flight
;
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) \
#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
View file @
5f4ef719
...
@@ -76,6 +76,68 @@
...
@@ -76,6 +76,68 @@
#include "iwl-fw-error-dump.h"
#include "iwl-fw-error-dump.h"
#include "internal.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
)
static
u32
iwl_trans_pcie_read_shr
(
struct
iwl_trans
*
trans
,
u32
reg
)
{
{
iwl_write32
(
trans
,
HEEP_CTRL_WRD_PCIEX_CTRL_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,
...
@@ -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
,
static
int
iwl_pcie_load_given_ucode
(
struct
iwl_trans
*
trans
,
const
struct
fw_img
*
image
)
const
struct
fw_img
*
image
)
{
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
int
ret
=
0
;
int
ret
=
0
;
int
first_ucode_section
;
int
first_ucode_section
;
...
@@ -733,6 +796,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
...
@@ -733,6 +796,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
return
ret
;
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 */
/* release CPU reset */
if
(
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_8000
)
if
(
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_8000
)
iwl_write_prph
(
trans
,
RELEASE_CPU_RESET
,
RELEASE_CPU_RESET_BIT
);
iwl_write_prph
(
trans
,
RELEASE_CPU_RESET
,
RELEASE_CPU_RESET_BIT
);
...
@@ -1126,6 +1203,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
...
@@ -1126,6 +1203,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
if
(
trans_pcie
->
napi
.
poll
)
if
(
trans_pcie
->
napi
.
poll
)
netif_napi_del
(
&
trans_pcie
->
napi
);
netif_napi_del
(
&
trans_pcie
->
napi
);
iwl_pcie_free_fw_monitor
(
trans
);
kfree
(
trans
);
kfree
(
trans
);
}
}
...
@@ -1494,10 +1573,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
...
@@ -1494,10 +1573,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
txq
=
&
trans_pcie
->
txq
[
cnt
];
txq
=
&
trans_pcie
->
txq
[
cnt
];
q
=
&
txq
->
q
;
q
=
&
txq
->
q
;
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
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
,
cnt
,
q
->
read_ptr
,
q
->
write_ptr
,
!!
test_bit
(
cnt
,
trans_pcie
->
queue_used
),
!!
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
);
ret
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
kfree
(
buf
);
kfree
(
buf
);
...
@@ -1519,6 +1600,10 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
...
@@ -1519,6 +1600,10 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
rxq
->
read
);
rxq
->
read
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"write: %u
\n
"
,
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"write: %u
\n
"
,
rxq
->
write
);
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
"
,
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"free_count: %u
\n
"
,
rxq
->
free_count
);
rxq
->
free_count
);
if
(
rxq
->
rb_stts
)
{
if
(
rxq
->
rb_stts
)
{
...
@@ -1698,10 +1783,15 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
...
@@ -1698,10 +1783,15 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
u32
len
;
u32
len
;
int
i
,
ptr
;
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
)
if
(
!
buf
)
return
sizeof
(
*
data
)
+
return
len
;
cmdq
->
q
.
n_window
*
(
sizeof
(
*
txcmd
)
+
TFD_MAX_PAYLOAD_SIZE
);
len
=
0
;
len
=
0
;
data
=
buf
;
data
=
buf
;
...
@@ -1729,7 +1819,40 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
...
@@ -1729,7 +1819,40 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
spin_unlock_bh
(
&
cmdq
->
lock
);
spin_unlock_bh
(
&
cmdq
->
lock
);
data
->
len
=
cpu_to_le32
(
len
);
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
#else
static
int
iwl_trans_pcie_dbgfs_register
(
struct
iwl_trans
*
trans
,
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,
...
@@ -1870,6 +1993,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
}
}
trans
->
hw_rev
=
iwl_read32
(
trans
,
CSR_HW_REV
);
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
;
trans
->
hw_id
=
(
pdev
->
device
<<
16
)
+
pdev
->
subsystem_device
;
snprintf
(
trans
->
hw_id_str
,
sizeof
(
trans
->
hw_id_str
),
snprintf
(
trans
->
hw_id_str
,
sizeof
(
trans
->
hw_id_str
),
"PCI ID: 0x%04X:0x%04X"
,
pdev
->
device
,
pdev
->
subsystem_device
);
"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,
...
@@ -1438,6 +1438,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
spin_unlock_irqrestore
(
&
trans_pcie
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
trans_pcie
->
reg_lock
,
flags
);
trans_pcie
->
cmd_in_flight
=
false
;
trans_pcie
->
cmd_in_flight
=
false
;
IWL_ERR
(
trans
,
"Failed to wake NIC for hcmd
\n
"
);
idx
=
-
EIO
;
idx
=
-
EIO
;
goto
out
;
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