Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
5f4ef719
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
5f4ef719
编写于
6月 25, 2014
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
上级
855df36d
c47af22a
变更
31
隐藏空白更改
内联
并排
Showing
31 changed file
with
609 addition
and
177 deletion
+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
未找到文件。
drivers/net/wireless/iwlwifi/dvm/power.c
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
{
...
...
@@ -136,7 +137,8 @@ struct iwl_ucode_tlv {
u8
data
[
0
];
};
#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
#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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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,20 +496,28 @@ 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
"
);
}
/* take the MAC address from the OTP */
hw_addr
=
(
const
u8
*
)(
nvm_hw
+
HW_ADDR0_FAMILY_8000
);
data
->
hw_addr
[
0
]
=
hw_addr
[
3
];
data
->
hw_addr
[
1
]
=
hw_addr
[
2
];
data
->
hw_addr
[
2
]
=
hw_addr
[
1
];
data
->
hw_addr
[
3
]
=
hw_addr
[
0
];
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
];
data
->
hw_addr
[
1
]
=
hw_addr
[
2
];
data
->
hw_addr
[
2
]
=
hw_addr
[
1
];
data
->
hw_addr
[
3
]
=
hw_addr
[
0
];
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
;
}
hw_addr
=
(
const
u8
*
)(
nvm_hw
+
HW_ADDR1_FAMILY_8000
);
data
->
hw_addr
[
4
]
=
hw_addr
[
1
];
data
->
hw_addr
[
5
]
=
hw_addr
[
0
];
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
;
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
;
/*
* 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
];
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
;
index
=
*
head
;
(
*
head
)
++
;
channel_number
[
index
]
=
cpu_to_le16
(
chan
->
hw_value
);
active_dwell
[
index
]
=
params
->
dwell
[
band
].
active
;
passive_dwell
[
index
]
=
params
->
dwell
[
band
].
passive
;
channels
->
iter_count
[
index
]
=
cpu_to_le16
(
1
);
channels
->
iter_interval
[
index
]
=
0
;
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录