Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
444474dd
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
444474dd
编写于
10月 18, 2013
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
上级
a72e25f7
246dd992
变更
41
展开全部
隐藏空白更改
内联
并排
Showing
41 changed file
with
3484 addition
and
1001 deletion
+3484
-1001
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-7000.c
+14
-0
drivers/net/wireless/iwlwifi/iwl-config.h
drivers/net/wireless/iwlwifi/iwl-config.h
+1
-0
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-csr.h
+32
-0
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-drv.c
+37
-0
drivers/net/wireless/iwlwifi/iwl-fw-file.h
drivers/net/wireless/iwlwifi/iwl-fw-file.h
+4
-0
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/iwl-fw.h
+25
-1
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl-prph.h
+2
-0
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+470
-162
drivers/net/wireless/iwlwifi/mvm/constants.h
drivers/net/wireless/iwlwifi/mvm/constants.h
+3
-1
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/d3.c
+476
-39
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
+154
-52
drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
+95
-54
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+67
-2
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+11
-0
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+28
-1
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+19
-2
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+30
-4
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+53
-2
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
+10
-6
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/fw.c
+18
-5
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+60
-15
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+209
-33
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+82
-6
drivers/net/wireless/iwlwifi/mvm/nvm.c
drivers/net/wireless/iwlwifi/mvm/nvm.c
+67
-34
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/ops.c
+44
-16
drivers/net/wireless/iwlwifi/mvm/power.c
drivers/net/wireless/iwlwifi/mvm/power.c
+57
-13
drivers/net/wireless/iwlwifi/mvm/quota.c
drivers/net/wireless/iwlwifi/mvm/quota.c
+37
-5
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rs.c
+403
-390
drivers/net/wireless/iwlwifi/mvm/rs.h
drivers/net/wireless/iwlwifi/mvm/rs.h
+96
-58
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/rx.c
+21
-0
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/scan.c
+444
-12
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.c
+157
-49
drivers/net/wireless/iwlwifi/mvm/sta.h
drivers/net/wireless/iwlwifi/mvm/sta.h
+0
-4
drivers/net/wireless/iwlwifi/mvm/testmode.h
drivers/net/wireless/iwlwifi/mvm/testmode.h
+95
-0
drivers/net/wireless/iwlwifi/mvm/time-event.c
drivers/net/wireless/iwlwifi/mvm/time-event.c
+3
-2
drivers/net/wireless/iwlwifi/mvm/time-event.h
drivers/net/wireless/iwlwifi/mvm/time-event.h
+3
-1
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+26
-23
drivers/net/wireless/iwlwifi/mvm/utils.c
drivers/net/wireless/iwlwifi/mvm/utils.c
+1
-1
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/drv.c
+4
-4
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+123
-4
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+3
-0
未找到文件。
drivers/net/wireless/iwlwifi/iwl-7000.c
浏览文件 @
444474dd
...
...
@@ -83,6 +83,8 @@
#define IWL7260_TX_POWER_VERSION 0xffff
/* meaningless */
#define IWL3160_NVM_VERSION 0x709
#define IWL3160_TX_POWER_VERSION 0xffff
/* meaningless */
#define IWL7265_NVM_VERSION 0x0a1d
#define IWL7265_TX_POWER_VERSION 0xffff
/* meaningless */
#define IWL7260_FW_PRE "iwlwifi-7260-"
#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
...
...
@@ -90,6 +92,9 @@
#define IWL3160_FW_PRE "iwlwifi-3160-"
#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode"
#define IWL7265_FW_PRE "iwlwifi-7265-"
#define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
static
const
struct
iwl_base_params
iwl7000_base_params
=
{
.
eeprom_size
=
OTP_LOW_IMAGE_SIZE
,
.
num_of_queues
=
IWLAGN_NUM_QUEUES
,
...
...
@@ -182,5 +187,14 @@ const struct iwl_cfg iwl3160_n_cfg = {
.
nvm_calib_ver
=
IWL3160_TX_POWER_VERSION
,
};
const
struct
iwl_cfg
iwl7265_2ac_cfg
=
{
.
name
=
"Intel(R) Dual Band Wireless AC 7265"
,
.
fw_name_pre
=
IWL7265_FW_PRE
,
IWL_DEVICE_7000
,
.
ht_params
=
&
iwl7000_ht_params
,
.
nvm_ver
=
IWL7265_NVM_VERSION
,
.
nvm_calib_ver
=
IWL7265_TX_POWER_VERSION
,
};
MODULE_FIRMWARE
(
IWL7260_MODULE_FIRMWARE
(
IWL7260_UCODE_API_OK
));
MODULE_FIRMWARE
(
IWL3160_MODULE_FIRMWARE
(
IWL3160_UCODE_API_OK
));
drivers/net/wireless/iwlwifi/iwl-config.h
浏览文件 @
444474dd
...
...
@@ -292,6 +292,7 @@ extern const struct iwl_cfg iwl7260_n_cfg;
extern
const
struct
iwl_cfg
iwl3160_2ac_cfg
;
extern
const
struct
iwl_cfg
iwl3160_2n_cfg
;
extern
const
struct
iwl_cfg
iwl3160_n_cfg
;
extern
const
struct
iwl_cfg
iwl7265_2ac_cfg
;
#endif
/* CONFIG_IWLMVM */
#endif
/* __IWL_CONFIG_H__ */
drivers/net/wireless/iwlwifi/iwl-csr.h
浏览文件 @
444474dd
...
...
@@ -394,6 +394,38 @@
#define CSR_DRAM_INT_TBL_ENABLE (1 << 31)
#define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27)
/* SECURE boot registers */
#define CSR_SECURE_BOOT_CONFIG_ADDR (0x100)
enum
secure_boot_config_reg
{
CSR_SECURE_BOOT_CONFIG_INSPECTOR_BURNED_IN_OTP
=
0x00000001
,
CSR_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ
=
0x00000002
,
};
#define CSR_SECURE_BOOT_CPU1_STATUS_ADDR (0x100)
#define CSR_SECURE_BOOT_CPU2_STATUS_ADDR (0x100)
enum
secure_boot_status_reg
{
CSR_SECURE_BOOT_CPU_STATUS_VERF_STATUS
=
0x00000003
,
CSR_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED
=
0x00000002
,
CSR_SECURE_BOOT_CPU_STATUS_VERF_SUCCESS
=
0x00000004
,
CSR_SECURE_BOOT_CPU_STATUS_VERF_FAIL
=
0x00000008
,
CSR_SECURE_BOOT_CPU_STATUS_SIGN_VERF_FAIL
=
0x00000010
,
};
#define CSR_UCODE_LOAD_STATUS_ADDR (0x100)
enum
secure_load_status_reg
{
CSR_CPU_STATUS_LOADING_STARTED
=
0x00000001
,
CSR_CPU_STATUS_LOADING_COMPLETED
=
0x00000002
,
CSR_CPU_STATUS_NUM_OF_LAST_COMPLETED
=
0x000000F8
,
CSR_CPU_STATUS_NUM_OF_LAST_LOADED_BLOCK
=
0x0000FF00
,
};
#define CSR_SECURE_INSPECTOR_CODE_ADDR (0x100)
#define CSR_SECURE_INSPECTOR_DATA_ADDR (0x100)
#define CSR_SECURE_TIME_OUT (100)
#define FH_TCSR_0_REG0 (0x1D00)
/*
* HBUS (Host-side Bus)
*
...
...
drivers/net/wireless/iwlwifi/iwl-drv.c
浏览文件 @
444474dd
...
...
@@ -483,6 +483,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
const
u8
*
tlv_data
;
char
buildstr
[
25
];
u32
build
;
int
num_of_cpus
;
if
(
len
<
sizeof
(
*
ucode
))
{
IWL_ERR
(
drv
,
"uCode has invalid length: %zd
\n
"
,
len
);
...
...
@@ -692,6 +693,42 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
goto
invalid_tlv_len
;
drv
->
fw
.
phy_config
=
le32_to_cpup
((
__le32
*
)
tlv_data
);
break
;
case
IWL_UCODE_TLV_SECURE_SEC_RT
:
iwl_store_ucode_sec
(
pieces
,
tlv_data
,
IWL_UCODE_REGULAR
,
tlv_len
);
drv
->
fw
.
mvm_fw
=
true
;
drv
->
fw
.
img
[
IWL_UCODE_REGULAR
].
is_secure
=
true
;
break
;
case
IWL_UCODE_TLV_SECURE_SEC_INIT
:
iwl_store_ucode_sec
(
pieces
,
tlv_data
,
IWL_UCODE_INIT
,
tlv_len
);
drv
->
fw
.
mvm_fw
=
true
;
drv
->
fw
.
img
[
IWL_UCODE_INIT
].
is_secure
=
true
;
break
;
case
IWL_UCODE_TLV_SECURE_SEC_WOWLAN
:
iwl_store_ucode_sec
(
pieces
,
tlv_data
,
IWL_UCODE_WOWLAN
,
tlv_len
);
drv
->
fw
.
mvm_fw
=
true
;
drv
->
fw
.
img
[
IWL_UCODE_WOWLAN
].
is_secure
=
true
;
break
;
case
IWL_UCODE_TLV_NUM_OF_CPU
:
if
(
tlv_len
!=
sizeof
(
u32
))
goto
invalid_tlv_len
;
num_of_cpus
=
le32_to_cpup
((
__le32
*
)
tlv_data
);
if
(
num_of_cpus
==
2
)
{
drv
->
fw
.
img
[
IWL_UCODE_REGULAR
].
is_dual_cpus
=
true
;
drv
->
fw
.
img
[
IWL_UCODE_INIT
].
is_dual_cpus
=
true
;
drv
->
fw
.
img
[
IWL_UCODE_WOWLAN
].
is_dual_cpus
=
true
;
}
else
if
((
num_of_cpus
>
2
)
||
(
num_of_cpus
<
1
))
{
IWL_ERR
(
drv
,
"Driver support upto 2 CPUs
\n
"
);
return
-
EINVAL
;
}
break
;
default:
IWL_DEBUG_INFO
(
drv
,
"unknown TLV: %d
\n
"
,
tlv_type
);
break
;
...
...
drivers/net/wireless/iwlwifi/iwl-fw-file.h
浏览文件 @
444474dd
...
...
@@ -121,6 +121,10 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_SEC_WOWLAN
=
21
,
IWL_UCODE_TLV_DEF_CALIB
=
22
,
IWL_UCODE_TLV_PHY_SKU
=
23
,
IWL_UCODE_TLV_SECURE_SEC_RT
=
24
,
IWL_UCODE_TLV_SECURE_SEC_INIT
=
25
,
IWL_UCODE_TLV_SECURE_SEC_WOWLAN
=
26
,
IWL_UCODE_TLV_NUM_OF_CPU
=
27
,
};
struct
iwl_ucode_tlv
{
...
...
drivers/net/wireless/iwlwifi/iwl-fw.h
浏览文件 @
444474dd
...
...
@@ -75,11 +75,23 @@
* @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
* @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
* @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
* @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
* offload profile config command.
* @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
* @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.
* @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
* (rather than two) IPv6 addresses
* @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
* @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
* from the probe request template.
* @IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API: modified D3 API to allow keeping
* connection when going back to D0
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
* @IWL_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan.
* @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
* @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
* containing CAM (Continuous Active Mode) indication.
*/
enum
iwl_ucode_tlv_flag
{
IWL_UCODE_TLV_FLAGS_PAN
=
BIT
(
0
),
...
...
@@ -87,11 +99,20 @@ enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_MFP
=
BIT
(
2
),
IWL_UCODE_TLV_FLAGS_P2P
=
BIT
(
3
),
IWL_UCODE_TLV_FLAGS_DW_BC_TABLE
=
BIT
(
4
),
IWL_UCODE_TLV_FLAGS_NEWBT_COEX
=
BIT
(
5
),
IWL_UCODE_TLV_FLAGS_UAPSD
=
BIT
(
6
),
IWL_UCODE_TLV_FLAGS_SHORT_BL
=
BIT
(
7
),
IWL_UCODE_TLV_FLAGS_RX_ENERGY_API
=
BIT
(
8
),
IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2
=
BIT
(
9
),
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS
=
BIT
(
10
),
IWL_UCODE_TLV_FLAGS_BF_UPDATED
=
BIT
(
11
),
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID
=
BIT
(
12
),
IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API
=
BIT
(
14
),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
=
BIT
(
15
),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE
=
BIT
(
16
),
IWL_UCODE_TLV_FLAGS_SCHED_SCAN
=
BIT
(
17
),
IWL_UCODE_TLV_FLAGS_STA_KEY_CMD
=
BIT
(
19
),
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
=
BIT
(
20
),
};
/* The default calibrate table size if not specified by firmware file */
...
...
@@ -133,7 +154,8 @@ enum iwl_ucode_sec {
* For 16.0 uCode and above, there is no differentiation between sections,
* just an offset to the HW address.
*/
#define IWL_UCODE_SECTION_MAX 4
#define IWL_UCODE_SECTION_MAX 6
#define IWL_UCODE_FIRST_SECTION_OF_SECOND_CPU (IWL_UCODE_SECTION_MAX/2)
struct
iwl_ucode_capabilities
{
u32
max_probe_length
;
...
...
@@ -150,6 +172,8 @@ struct fw_desc {
struct
fw_img
{
struct
fw_desc
sec
[
IWL_UCODE_SECTION_MAX
];
bool
is_secure
;
bool
is_dual_cpus
;
};
/* uCode version contains 4 values: Major/Minor/API/Serial */
...
...
drivers/net/wireless/iwlwifi/iwl-prph.h
浏览文件 @
444474dd
...
...
@@ -97,6 +97,8 @@
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
#define APMG_RTC_INT_STT_RFKILL (0x10000000)
/* Device system time */
#define DEVICE_SYSTEM_TIME_REG 0xA0206C
...
...
drivers/net/wireless/iwlwifi/mvm/bt-coex.c
浏览文件 @
444474dd
此差异已折叠。
点击以展开。
drivers/net/wireless/iwlwifi/mvm/constants.h
浏览文件 @
444474dd
...
...
@@ -70,7 +70,9 @@
#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20
#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 20
#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8
#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30
#define IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20
#define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50
#define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50
#define IWL_MVM_PS_SNOOZE_INTERVAL 25
...
...
drivers/net/wireless/iwlwifi/mvm/d3.c
浏览文件 @
444474dd
此差异已折叠。
点击以展开。
drivers/net/wireless/iwlwifi/mvm/debugfs.c
浏览文件 @
444474dd
...
...
@@ -246,58 +246,56 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
}
static
ssize_t
iwl_dbgfs_
power_down_allow_write
(
struct
file
*
file
,
c
onst
c
har
__user
*
user_buf
,
static
ssize_t
iwl_dbgfs_
disable_power_off_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_mvm
*
mvm
=
file
->
private_data
;
char
buf
[
8
]
=
{};
int
allow
;
if
(
!
mvm
->
ucode_loaded
)
return
-
EIO
;
if
(
copy_from_user
(
buf
,
user_buf
,
sizeof
(
buf
)))
return
-
EFAULT
;
if
(
sscanf
(
buf
,
"%d"
,
&
allow
)
!=
1
)
return
-
EINVAL
;
IWL_DEBUG_POWER
(
mvm
,
"%s device power down
\n
"
,
allow
?
"allow"
:
"prevent"
);
char
buf
[
64
];
int
bufsz
=
sizeof
(
buf
);
int
pos
=
0
;
/*
* TODO: Send REPLY_DEBUG_CMD (0xf0) when FW support it
*/
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"disable_power_off_d0=%d
\n
"
,
mvm
->
disable_power_off
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"disable_power_off_d3=%d
\n
"
,
mvm
->
disable_power_off_d3
);
return
count
;
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
)
;
}
static
ssize_t
iwl_dbgfs_
power_down_d3_allow
_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
static
ssize_t
iwl_dbgfs_
disable_power_off
_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_mvm
*
mvm
=
file
->
private_data
;
char
buf
[
8
]
=
{};
int
allow
;
char
buf
[
64
]
=
{};
int
ret
;
int
val
;
if
(
copy_from_user
(
buf
,
user_buf
,
sizeof
(
buf
)))
if
(
!
mvm
->
ucode_loaded
)
return
-
EIO
;
count
=
min_t
(
size_t
,
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
count
))
return
-
EFAULT
;
if
(
sscanf
(
buf
,
"%d"
,
&
allow
)
!=
1
)
if
(
!
strncmp
(
"disable_power_off_d0="
,
buf
,
21
))
{
if
(
sscanf
(
buf
+
21
,
"%d"
,
&
val
)
!=
1
)
return
-
EINVAL
;
mvm
->
disable_power_off
=
val
;
}
else
if
(
!
strncmp
(
"disable_power_off_d3="
,
buf
,
21
))
{
if
(
sscanf
(
buf
+
21
,
"%d"
,
&
val
)
!=
1
)
return
-
EINVAL
;
mvm
->
disable_power_off_d3
=
val
;
}
else
{
return
-
EINVAL
;
}
IWL_DEBUG_POWER
(
mvm
,
"%s device power down in d3
\n
"
,
allow
?
"allow"
:
"prevent"
);
/*
* TODO: When WoWLAN FW alive notification happens, driver will send
* REPLY_DEBUG_CMD setting power_down_allow flag according to
* mvm->prevent_power_down_d3
*/
mvm
->
prevent_power_down_d3
=
!
allow
;
mutex_lock
(
&
mvm
->
mutex
);
ret
=
iwl_mvm_power_update_device_mode
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
return
count
;
return
ret
?:
count
;
}
static
void
iwl_dbgfs_update_pm
(
struct
iwl_mvm
*
mvm
,
...
...
@@ -371,7 +369,8 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
int
val
;
int
ret
;
if
(
copy_from_user
(
buf
,
user_buf
,
sizeof
(
buf
)))
count
=
min_t
(
size_t
,
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
count
))
return
-
EFAULT
;
if
(
!
strncmp
(
"keep_alive="
,
buf
,
11
))
{
...
...
@@ -394,7 +393,9 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
if
(
sscanf
(
buf
+
16
,
"%d"
,
&
val
)
!=
1
)
return
-
EINVAL
;
param
=
MVM_DEBUGFS_PM_TX_DATA_TIMEOUT
;
}
else
if
(
!
strncmp
(
"disable_power_off="
,
buf
,
18
))
{
}
else
if
(
!
strncmp
(
"disable_power_off="
,
buf
,
18
)
&&
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
))
{
if
(
sscanf
(
buf
+
18
,
"%d"
,
&
val
)
!=
1
)
return
-
EINVAL
;
param
=
MVM_DEBUGFS_PM_DISABLE_POWER_OFF
;
...
...
@@ -581,15 +582,21 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
BT_MBOX_PRINT
(
3
,
UPDATE_REQUEST
,
true
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_status = %d
\n
"
,
notif
->
bt_status
);
notif
->
bt_status
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_open_conn = %d
\n
"
,
notif
->
bt_open_conn
);
notif
->
bt_open_conn
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_traffic_load = %d
\n
"
,
notif
->
bt_traffic_load
);
notif
->
bt_traffic_load
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_agg_traffic_load = %d
\n
"
,
notif
->
bt_agg_traffic_load
);
notif
->
bt_agg_traffic_load
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_ci_compliance = %d
\n
"
,
notif
->
bt_ci_compliance
);
notif
->
bt_ci_compliance
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"primary_ch_lut = %d
\n
"
,
le32_to_cpu
(
notif
->
primary_ch_lut
));
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"secondary_ch_lut = %d
\n
"
,
le32_to_cpu
(
notif
->
secondary_ch_lut
));
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_activity_grading = %d
\n
"
,
le32_to_cpu
(
notif
->
bt_activity_grading
));
mutex_unlock
(
&
mvm
->
mutex
);
...
...
@@ -600,6 +607,38 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
}
#undef BT_MBOX_PRINT
static
ssize_t
iwl_dbgfs_bt_cmd_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_mvm
*
mvm
=
file
->
private_data
;
struct
iwl_bt_coex_ci_cmd
*
cmd
=
&
mvm
->
last_bt_ci_cmd
;
char
buf
[
256
];
int
bufsz
=
sizeof
(
buf
);
int
pos
=
0
;
mutex_lock
(
&
mvm
->
mutex
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"Channel inhibition CMD
\n
"
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"
\t
Primary Channel Bitmap 0x%016llx Fat: %d
\n
"
,
le64_to_cpu
(
cmd
->
bt_primary_ci
),
!!
cmd
->
co_run_bw_primary
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"
\t
Secondary Channel Bitmap 0x%016llx Fat: %d
\n
"
,
le64_to_cpu
(
cmd
->
bt_secondary_ci
),
!!
cmd
->
co_run_bw_secondary
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"BT Configuration CMD
\n
"
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"
\t
ACK Kill Mask 0x%08x
\n
"
,
iwl_bt_ack_kill_msk
[
mvm
->
bt_kill_msk
]);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"
\t
CTS Kill Mask 0x%08x
\n
"
,
iwl_bt_cts_kill_msk
[
mvm
->
bt_kill_msk
]);
mutex_unlock
(
&
mvm
->
mutex
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
}
#define PRINT_STATS_LE32(_str, _val) \
pos += scnprintf(buf + pos, bufsz - pos, \
fmt_table, _str, \
...
...
@@ -615,9 +654,11 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
int
pos
=
0
;
char
*
buf
;
int
ret
;
int
bufsz
=
sizeof
(
struct
mvm_statistics_rx_phy
)
*
20
+
sizeof
(
struct
mvm_statistics_rx_non_phy
)
*
10
+
sizeof
(
struct
mvm_statistics_rx_ht_phy
)
*
10
+
200
;
/* 43 is the size of each data line, 33 is the size of each header */
size_t
bufsz
=
((
sizeof
(
struct
mvm_statistics_rx
)
/
sizeof
(
__le32
))
*
43
)
+
(
4
*
33
)
+
1
;
struct
mvm_statistics_rx_phy
*
ofdm
;
struct
mvm_statistics_rx_phy
*
cck
;
struct
mvm_statistics_rx_non_phy
*
general
;
...
...
@@ -712,6 +753,7 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
PRINT_STATS_LE32
(
"beacon_energy_b"
,
general
->
beacon_energy_b
);
PRINT_STATS_LE32
(
"beacon_energy_c"
,
general
->
beacon_energy_c
);
PRINT_STATS_LE32
(
"num_bt_kills"
,
general
->
num_bt_kills
);
PRINT_STATS_LE32
(
"mac_id"
,
general
->
mac_id
);
PRINT_STATS_LE32
(
"directed_data_mpdu"
,
general
->
directed_data_mpdu
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
fmt_header
,
...
...
@@ -757,6 +799,59 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
return
count
;
}
static
ssize_t
iwl_dbgfs_scan_ant_rxchain_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_mvm
*
mvm
=
file
->
private_data
;
int
pos
=
0
;
char
buf
[
32
];
const
size_t
bufsz
=
sizeof
(
buf
);
/* print which antennas were set for the scan command by the user */
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"Antennas for scan: "
);
if
(
mvm
->
scan_rx_ant
&
ANT_A
)
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"A"
);
if
(
mvm
->
scan_rx_ant
&
ANT_B
)
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"B"
);
if
(
mvm
->
scan_rx_ant
&
ANT_C
)
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"C"
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
" (%hhx)
\n
"
,
mvm
->
scan_rx_ant
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
}
static
ssize_t
iwl_dbgfs_scan_ant_rxchain_write
(
struct
file
*
file
,
const
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_mvm
*
mvm
=
file
->
private_data
;
char
buf
[
8
];
int
buf_size
;
u8
scan_rx_ant
;
memset
(
buf
,
0
,
sizeof
(
buf
));
buf_size
=
min
(
count
,
sizeof
(
buf
)
-
1
);
/* get the argument from the user and check if it is valid */
if
(
copy_from_user
(
buf
,
user_buf
,
buf_size
))
return
-
EFAULT
;
if
(
sscanf
(
buf
,
"%hhx"
,
&
scan_rx_ant
)
!=
1
)
return
-
EINVAL
;
if
(
scan_rx_ant
>
ANT_ABC
)
return
-
EINVAL
;
if
(
scan_rx_ant
&
~
iwl_fw_valid_rx_ant
(
mvm
->
fw
))
return
-
EINVAL
;
/* change the rx antennas for scan command */
mvm
->
scan_rx_ant
=
scan_rx_ant
;
return
count
;
}
static
void
iwl_dbgfs_update_bf
(
struct
ieee80211_vif
*
vif
,
enum
iwl_dbgfs_bf_mask
param
,
int
value
)
{
...
...
@@ -968,7 +1063,8 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
char
buf
[
8
]
=
{};
int
store
;
if
(
copy_from_user
(
buf
,
user_buf
,
sizeof
(
buf
)))
count
=
min_t
(
size_t
,
count
,
sizeof
(
buf
)
-
1
);
if
(
copy_from_user
(
buf
,
user_buf
,
count
))
return
-
EFAULT
;
if
(
sscanf
(
buf
,
"%d"
,
&
store
)
!=
1
)
...
...
@@ -1063,10 +1159,12 @@ MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
sram
);
MVM_DEBUGFS_READ_FILE_OPS
(
stations
);
MVM_DEBUGFS_READ_FILE_OPS
(
bt_notif
);
MVM_DEBUGFS_
WRITE_FILE_OPS
(
power_down_allow
);
MVM_DEBUGFS_
WRITE_FILE_OPS
(
power_down_d3_allow
);
MVM_DEBUGFS_
READ_FILE_OPS
(
bt_cmd
);
MVM_DEBUGFS_
READ_WRITE_FILE_OPS
(
disable_power_off
);
MVM_DEBUGFS_READ_FILE_OPS
(
fw_rx_stats
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_restart
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
scan_ant_rxchain
);
#ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
d3_sram
);
#endif
...
...
@@ -1087,10 +1185,14 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE
(
sram
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
stations
,
dbgfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_notif
,
dbgfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
power_down_allow
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
power_down_d3_allow
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_cmd
,
dbgfs_dir
,
S_IRUSR
);
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
)
MVM_DEBUGFS_ADD_FILE
(
disable_power_off
,
mvm
->
debugfs_dir
,
S_IRUSR
|
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_rx_stats
,
mvm
->
debugfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_restart
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
scan_ant_rxchain
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
#ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_ADD_FILE
(
d3_sram
,
mvm
->
debugfs_dir
,
S_IRUSR
|
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
d3_test
,
mvm
->
debugfs_dir
,
S_IRUSR
);
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
浏览文件 @
444474dd
...
...
@@ -82,6 +82,8 @@
* @BT_USE_DEFAULTS:
* @BT_SYNC_2_BT_DISABLE:
* @BT_COEX_CORUNNING_TBL_EN:
*
* The COEX_MODE must be set for each command. Even if it is not changed.
*/
enum
iwl_bt_coex_flags
{
BT_CH_PRIMARY_EN
=
BIT
(
0
),
...
...
@@ -95,14 +97,16 @@ enum iwl_bt_coex_flags {
BT_COEX_NW
=
0x3
<<
BT_COEX_MODE_POS
,
BT_USE_DEFAULTS
=
BIT
(
6
),
BT_SYNC_2_BT_DISABLE
=
BIT
(
7
),
/*
* For future use - when the flags will be enlarged
* BT_COEX_CORUNNING_TBL_EN = BIT(8),
*/
BT_COEX_CORUNNING_TBL_EN
=
BIT
(
8
),
BT_COEX_MPLUT_TBL_EN
=
BIT
(
9
),
/* Bit 10 is reserved */
BT_COEX_WF_PRIO_BOOST_CHECK_EN
=
BIT
(
11
),
};
/*
* indicates what has changed in the BT_COEX command.
* BT_VALID_ENABLE must be set for each command. Commands without this bit will
* discarded by the firmware
*/
enum
iwl_bt_coex_valid_bit_msk
{
BT_VALID_ENABLE
=
BIT
(
0
),
...
...
@@ -121,11 +125,8 @@ enum iwl_bt_coex_valid_bit_msk {
BT_VALID_CORUN_LUT_40
=
BIT
(
13
),
BT_VALID_ANT_ISOLATION
=
BIT
(
14
),
BT_VALID_ANT_ISOLATION_THRS
=
BIT
(
15
),
/*
* For future use - when the valid flags will be enlarged
* BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
* BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
*/
BT_VALID_TXTX_DELTA_FREQ_THRS
=
BIT
(
16
),
BT_VALID_TXRX_MAX_FREQ_0
=
BIT
(
17
),
};
/**
...
...
@@ -142,48 +143,88 @@ enum iwl_bt_reduced_tx_power {
BT_REDUCED_TX_POWER_DATA
=
BIT
(
1
),
};
enum
iwl_bt_coex_lut_type
{
BT_COEX_TIGHT_LUT
=
0
,
BT_COEX_LOOSE_LUT
,
BT_COEX_TX_DIS_LUT
,
BT_COEX_MAX_LUT
,
};
#define BT_COEX_LUT_SIZE (12)
#define BT_COEX_CORUN_LUT_SIZE (32)
#define BT_COEX_MULTI_PRIO_LUT_SIZE (2)
#define BT_COEX_BOOST_SIZE (4)
#define BT_REDUCED_TX_POWER_BIT BIT(7)
/**
* struct iwl_bt_coex_cmd - bt coex configuration command
* @flags:&enum iwl_bt_coex_flags
* @lead_time:
* @max_kill:
* @bt3_time_t7_value:
* @kill_ack_msk:
* @kill_cts_msk:
* @bt3_prio_sample_time:
* @bt3_timer_t2_value:
* @bt4_reaction_time:
* @decision_lut[12]:
* @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
* @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
* @bt_prio_boost: values for PTA boost register
* @bt4_antenna_isolation:
* @bt4_antenna_isolation_thr:
* @bt4_tx_tx_delta_freq_thr:
* @bt4_tx_rx_max_freq0:
* @bt_prio_boost:
* @wifi_tx_prio_boost: SW boost of wifi tx priority
* @wifi_rx_prio_boost: SW boost of wifi rx priority
* @kill_ack_msk:
* @kill_cts_msk:
* @decision_lut:
* @bt4_multiprio_lut:
* @bt4_corun_lut20:
* @bt4_corun_lut40:
* @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
*
* The structure is used for the BT_COEX command.
*/
struct
iwl_bt_coex_cmd
{
u8
flags
;
u8
lead_time
;
__le32
flags
;
u8
max_kill
;
u8
bt3_time_t7_value
;
u8
bt_reduced_tx_power
;
u8
reserved
[
2
];
u8
bt4_antenna_isolation
;
u8
bt4_antenna_isolation_thr
;
u8
bt4_tx_tx_delta_freq_thr
;
u8
bt4_tx_rx_max_freq0
;
__le32
bt_prio_boost
[
BT_COEX_BOOST_SIZE
];
__le32
wifi_tx_prio_boost
;
__le32
wifi_rx_prio_boost
;
__le32
kill_ack_msk
;
__le32
kill_cts_msk
;
u8
bt3_prio_sample_time
;
u8
bt3_timer_t2_value
;
__le16
bt4_reaction_time
;
__le32
decision_lut
[
BT_COEX_LUT_SIZE
];
u8
bt_reduced_tx_power
;
u8
reserved
;
__le16
valid_bit_msk
;
__le32
bt_prio_boost
;
u8
reserved2
;
u8
wifi_tx_prio_boost
;
__le16
wifi_rx_prio_boost
;
__le32
decision_lut
[
BT_COEX_MAX_LUT
][
BT_COEX_LUT_SIZE
];
__le32
bt4_multiprio_lut
[
BT_COEX_MULTI_PRIO_LUT_SIZE
];
__le32
bt4_corun_lut20
[
BT_COEX_CORUN_LUT_SIZE
];
__le32
bt4_corun_lut40
[
BT_COEX_CORUN_LUT_SIZE
];
__le32
valid_bit_msk
;
}
__packed
;
/* BT_COEX_CMD_API_S_VER_3 */
/**
* struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command
* @bt_primary_ci:
* @bt_secondary_ci:
* @co_run_bw_primary:
* @co_run_bw_secondary:
* @primary_ch_phy_id:
* @secondary_ch_phy_id:
*
* Used for BT_COEX_CI command
*/
struct
iwl_bt_coex_ci_cmd
{
__le64
bt_primary_ci
;
__le64
bt_secondary_ci
;
u8
co_run_bw_primary
;
u8
co_run_bw_secondary
;
u8
primary_ch_phy_id
;
u8
secondary_ch_phy_id
;
}
__packed
;
/* BT_CI_MSG_API_S_VER_1 */
#define BT_MBOX(n_dw, _msg, _pos, _nbits) \
BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS
...
...
@@ -244,23 +285,39 @@ enum iwl_bt_mxbox_dw3 {
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS)
enum
iwl_bt_activity_grading
{
BT_OFF
=
0
,
BT_ON_NO_CONNECTION
=
1
,
BT_LOW_TRAFFIC
=
2
,
BT_HIGH_TRAFFIC
=
3
,
};
/**
* struct iwl_bt_coex_profile_notif - notification about BT coex
* @mbox_msg: message from BT to WiFi
* @:bt_status: 0 - off, 1 - on
* @:bt_open_conn: number of BT connections open
* @: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
* @msg_idx: the index of the message
* @bt_status: 0 - off, 1 - on
* @bt_open_conn: number of BT connections open
* @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
* @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
*/
struct
iwl_bt_coex_profile_notif
{
__le32
mbox_msg
[
4
];
__le32
msg_idx
;
u8
bt_status
;
u8
bt_open_conn
;
u8
bt_traffic_load
;
u8
bt_agg_traffic_load
;
u8
bt_ci_compliance
;
u8
reserved
[
3
];
__le32
primary_ch_lut
;
__le32
secondary_ch_lut
;
__le32
bt_activity_grading
;
}
__packed
;
/* BT_COEX_PROFILE_NTFY_API_S_VER_2 */
enum
iwl_bt_coex_prio_table_event
{
...
...
@@ -300,20 +357,4 @@ struct iwl_bt_coex_prio_tbl_cmd {
u8
prio_tbl
[
BT_COEX_PRIO_TBL_EVT_MAX
];
}
__packed
;
enum
iwl_bt_coex_env_action
{
BT_COEX_ENV_CLOSE
=
0
,
BT_COEX_ENV_OPEN
=
1
,
};
/* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */
/**
* struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope
* @action: enum %iwl_bt_coex_env_action
* @type: enum %iwl_bt_coex_prio_table_event
*/
struct
iwl_bt_coex_prot_env_cmd
{
u8
action
;
/* 0 = closed, 1 = open */
u8
type
;
/* 0 .. 15 */
u8
reserved
[
2
];
}
__packed
;
#endif
/* __fw_api_bt_coex_h__ */
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
浏览文件 @
444474dd
...
...
@@ -100,7 +100,12 @@ enum iwl_proto_offloads {
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2 6
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 6
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L 12
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S 4
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 12
#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L 4
#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S 2
/**
* struct iwl_proto_offload_cmd_common - ARP/NS offload common part
...
...
@@ -155,6 +160,43 @@ struct iwl_proto_offload_cmd_v2 {
u8
reserved2
[
3
];
}
__packed
;
/* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */
struct
iwl_ns_config
{
struct
in6_addr
source_ipv6_addr
;
struct
in6_addr
dest_ipv6_addr
;
u8
target_mac_addr
[
ETH_ALEN
];
__le16
reserved
;
}
__packed
;
/* NS_OFFLOAD_CONFIG */
struct
iwl_targ_addr
{
struct
in6_addr
addr
;
__le32
config_num
;
}
__packed
;
/* TARGET_IPV6_ADDRESS */
/**
* struct iwl_proto_offload_cmd_v3_small - ARP/NS offload configuration
* @common: common/IPv4 configuration
* @target_ipv6_addr: target IPv6 addresses
* @ns_config: NS offload configurations
*/
struct
iwl_proto_offload_cmd_v3_small
{
struct
iwl_proto_offload_cmd_common
common
;
__le32
num_valid_ipv6_addrs
;
struct
iwl_targ_addr
targ_addrs
[
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S
];
struct
iwl_ns_config
ns_config
[
IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S
];
}
__packed
;
/* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */
/**
* struct iwl_proto_offload_cmd_v3_large - ARP/NS offload configuration
* @common: common/IPv4 configuration
* @target_ipv6_addr: target IPv6 addresses
* @ns_config: NS offload configurations
*/
struct
iwl_proto_offload_cmd_v3_large
{
struct
iwl_proto_offload_cmd_common
common
;
__le32
num_valid_ipv6_addrs
;
struct
iwl_targ_addr
targ_addrs
[
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L
];
struct
iwl_ns_config
ns_config
[
IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L
];
}
__packed
;
/* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */
/*
* WOWLAN_PATTERNS
...
...
@@ -293,7 +335,7 @@ enum iwl_wowlan_wakeup_reason {
IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET
=
BIT
(
12
),
};
/* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
struct
iwl_wowlan_status
{
struct
iwl_wowlan_status
_v4
{
__le64
replay_ctr
;
__le16
pattern_number
;
__le16
non_qos_seq_ctr
;
...
...
@@ -308,6 +350,29 @@ struct iwl_wowlan_status {
u8
wake_packet
[];
/* can be truncated from _length to _bufsize */
}
__packed
;
/* WOWLAN_STATUSES_API_S_VER_4 */
struct
iwl_wowlan_gtk_status
{
u8
key_index
;
u8
reserved
[
3
];
u8
decrypt_key
[
16
];
u8
tkip_mic_key
[
8
];
struct
iwl_wowlan_rsc_tsc_params_cmd
rsc
;
}
__packed
;
struct
iwl_wowlan_status_v6
{
struct
iwl_wowlan_gtk_status
gtk
;
__le64
replay_ctr
;
__le16
pattern_number
;
__le16
non_qos_seq_ctr
;
__le16
qos_seq_ctr
[
8
];
__le32
wakeup_reasons
;
__le32
num_of_gtk_rekeys
;
__le32
transmitted_ndps
;
__le32
received_beacons
;
__le32
wake_packet_length
;
__le32
wake_packet_bufsize
;
u8
wake_packet
[];
/* can be truncated from _length to _bufsize */
}
__packed
;
/* WOWLAN_STATUSES_API_S_VER_6 */
#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64
#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128
#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
浏览文件 @
444474dd
...
...
@@ -170,12 +170,14 @@ struct iwl_mac_data_ap {
* @beacon_tsf: beacon transmit time in TSF
* @bi: beacon interval in TU
* @bi_reciprocal: 2^32 / bi
* @beacon_template: beacon template ID
*/
struct
iwl_mac_data_ibss
{
__le32
beacon_time
;
__le64
beacon_tsf
;
__le32
bi
;
__le32
bi_reciprocal
;
__le32
beacon_template
;
}
__packed
;
/* IBSS_MAC_DATA_API_S_VER_1 */
/**
...
...
@@ -372,4 +374,13 @@ static inline u32 iwl_mvm_reciprocal(u32 v)
return
0xFFFFFFFF
/
v
;
}
#define IWL_NONQOS_SEQ_GET 0x1
#define IWL_NONQOS_SEQ_SET 0x2
struct
iwl_nonqos_seq_query_cmd
{
__le32
get_set_flag
;
__le32
mac_id_n_color
;
__le16
value
;
__le16
reserved
;
}
__packed
;
/* NON_QOS_TX_COUNTER_GET_SET_API_S_VER_1 */
#endif
/* __fw_api_mac_h__ */
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
浏览文件 @
444474dd
...
...
@@ -131,6 +131,33 @@ struct iwl_powertable_cmd {
__le32
lprx_rssi_threshold
;
}
__packed
;
/**
* enum iwl_device_power_flags - masks for device power command flags
* @DEVIC_POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
* receiver and transmitter. '0' - does not allow. This flag should be
* always set to '1' unless one need to disable actual power down for debug
* purposes.
* @DEVICE_POWER_FLAGS_CAM_MSK: '1' CAM (Continuous Active Mode) is set, meaning
* that power management is disabled. '0' Power management is enabled, one
* of power schemes is applied.
*/
enum
iwl_device_power_flags
{
DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK
=
BIT
(
0
),
DEVICE_POWER_FLAGS_CAM_MSK
=
BIT
(
13
),
};
/**
* struct iwl_device_power_cmd - device wide power command.
* DEVICE_POWER_CMD = 0x77 (command, has simple generic response)
*
* @flags: Power table command flags from DEVICE_POWER_FLAGS_*
*/
struct
iwl_device_power_cmd
{
/* PM_POWER_TABLE_CMD_API_S_VER_6 */
__le16
flags
;
__le16
reserved
;
}
__packed
;
/**
* struct iwl_mac_power_cmd - New power command containing uAPSD support
* MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response)
...
...
@@ -290,7 +317,7 @@ struct iwl_beacon_filter_cmd {
#define IWL_BF_ESCAPE_TIMER_MIN 0
#define IWL_BA_ESCAPE_TIMER_DEFAULT 6
#define IWL_BA_ESCAPE_TIMER_D3
6
#define IWL_BA_ESCAPE_TIMER_D3
9
#define IWL_BA_ESCAPE_TIMER_MAX 1024
#define IWL_BA_ESCAPE_TIMER_MIN 0
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
浏览文件 @
444474dd
...
...
@@ -68,6 +68,7 @@
/*
* These serve as indexes into
* struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
* TODO: avoid overlap between legacy and HT rates
*/
enum
{
IWL_RATE_1M_INDEX
=
0
,
...
...
@@ -78,18 +79,31 @@ enum {
IWL_LAST_CCK_RATE
=
IWL_RATE_11M_INDEX
,
IWL_RATE_6M_INDEX
,
IWL_FIRST_OFDM_RATE
=
IWL_RATE_6M_INDEX
,
IWL_RATE_MCS_0_INDEX
=
IWL_RATE_6M_INDEX
,
IWL_FIRST_HT_RATE
=
IWL_RATE_MCS_0_INDEX
,
IWL_FIRST_VHT_RATE
=
IWL_RATE_MCS_0_INDEX
,
IWL_RATE_9M_INDEX
,
IWL_RATE_12M_INDEX
,
IWL_RATE_MCS_1_INDEX
=
IWL_RATE_12M_INDEX
,
IWL_RATE_18M_INDEX
,
IWL_RATE_MCS_2_INDEX
=
IWL_RATE_18M_INDEX
,
IWL_RATE_24M_INDEX
,
IWL_RATE_MCS_3_INDEX
=
IWL_RATE_24M_INDEX
,
IWL_RATE_36M_INDEX
,
IWL_RATE_MCS_4_INDEX
=
IWL_RATE_36M_INDEX
,
IWL_RATE_48M_INDEX
,
IWL_RATE_MCS_5_INDEX
=
IWL_RATE_48M_INDEX
,
IWL_RATE_54M_INDEX
,
IWL_RATE_MCS_6_INDEX
=
IWL_RATE_54M_INDEX
,
IWL_LAST_NON_HT_RATE
=
IWL_RATE_54M_INDEX
,
IWL_RATE_60M_INDEX
,
IWL_LAST_OFDM_RATE
=
IWL_RATE_60M_INDEX
,
IWL_RATE_MCS_7_INDEX
=
IWL_RATE_60M_INDEX
,
IWL_LAST_HT_RATE
=
IWL_RATE_MCS_7_INDEX
,
IWL_RATE_MCS_8_INDEX
,
IWL_RATE_MCS_9_INDEX
,
IWL_LAST_VHT_RATE
=
IWL_RATE_MCS_9_INDEX
,
IWL_RATE_COUNT_LEGACY
=
IWL_LAST_NON_HT_RATE
+
1
,
IWL_RATE_COUNT
,
IWL_RATE_COUNT
=
IWL_LAST_VHT_RATE
+
1
,
};
#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX)
...
...
@@ -108,6 +122,7 @@ enum {
IWL_RATE_2M_PLCP
=
20
,
IWL_RATE_5M_PLCP
=
55
,
IWL_RATE_11M_PLCP
=
110
,
IWL_RATE_INVM_PLCP
=
-
1
,
};
/*
...
...
@@ -164,6 +179,8 @@ enum {
* which is the duplicate 20 MHz MCS (bit 5 set, all others zero.)
*/
#define RATE_HT_MCS_RATE_CODE_MSK 0x7
#define RATE_HT_MCS_NSS_POS 3
#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS)
/* Bit 10: (1) Use Green Field preamble */
#define RATE_HT_MCS_GF_POS 10
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
浏览文件 @
444474dd
...
...
@@ -356,6 +356,7 @@ struct iwl_scan_complete_notif {
/* 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
#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
...
...
@@ -368,6 +369,12 @@ struct iwl_scan_complete_notif {
#define IWL_FULL_SCAN_MULTIPLIER 5
#define IWL_FAST_SCHED_SCAN_ITERATIONS 3
enum
scan_framework_client
{
SCAN_CLIENT_SCHED_SCAN
=
BIT
(
0
),
SCAN_CLIENT_NETDETECT
=
BIT
(
1
),
SCAN_CLIENT_ASSET_TRACKING
=
BIT
(
2
),
};
/**
* struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6
* @scan_flags: see enum iwl_scan_flags
...
...
@@ -449,11 +456,12 @@ struct iwl_scan_offload_cfg {
* iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S
* @ssid: MAC address to filter out
* @reported_rssi: AP rssi reported to the host
* @client_bitmap: clients ignore this entry - enum scan_framework_client
*/
struct
iwl_scan_offload_blacklist
{
u8
ssid
[
ETH_ALEN
];
u8
reported_rssi
;
u8
reserved
;
u8
client_bitmap
;
}
__packed
;
enum
iwl_scan_offload_network_type
{
...
...
@@ -475,6 +483,7 @@ enum iwl_scan_offload_band_selection {
* @aut_alg: authentication olgorithm to match - bitmap
* @network_type: enum iwl_scan_offload_network_type
* @band_selection: enum iwl_scan_offload_band_selection
* @client_bitmap: clients waiting for match - enum scan_framework_client
*/
struct
iwl_scan_offload_profile
{
u8
ssid_index
;
...
...
@@ -482,7 +491,8 @@ struct iwl_scan_offload_profile {
u8
auth_alg
;
u8
network_type
;
u8
band_selection
;
u8
reserved
[
3
];
u8
client_bitmap
;
u8
reserved
[
2
];
}
__packed
;
/**
...
...
@@ -491,13 +501,18 @@ struct iwl_scan_offload_profile {
* @profiles: profiles to search for match
* @blacklist_len: length of blacklist
* @num_profiles: num of profiles in the list
* @match_notify: clients waiting for match found notification
* @pass_match: clients waiting for the results
* @active_clients: active clients bitmap - enum scan_framework_client
*/
struct
iwl_scan_offload_profile_cfg
{
struct
iwl_scan_offload_blacklist
blacklist
[
IWL_SCAN_MAX_BLACKLIST_LEN
];
struct
iwl_scan_offload_profile
profiles
[
IWL_SCAN_MAX_PROFILES
];
u8
blacklist_len
;
u8
num_profiles
;
u8
reserved
[
2
];
u8
match_notify
;
u8
pass_match
;
u8
active_clients
;
u8
reserved
[
3
];
}
__packed
;
/**
...
...
@@ -560,4 +575,15 @@ struct iwl_scan_offload_complete {
u8
reserved
;
}
__packed
;
/**
* iwl_sched_scan_results - SCAN_OFFLOAD_MATCH_FOUND_NTF_API_S_VER_1
* @ssid_bitmap: SSIDs indexes found in this iteration
* @client_bitmap: clients that are active and wait for this notification
*/
struct
iwl_sched_scan_results
{
__le16
ssid_bitmap
;
u8
client_bitmap
;
u8
reserved
;
};
#endif
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
浏览文件 @
444474dd
...
...
@@ -247,7 +247,7 @@ struct iwl_mvm_keyinfo {
}
__packed
;
/**
* struct iwl_mvm_add_sta_cmd
- Add / modify a station in the fw's station table
* struct iwl_mvm_add_sta_cmd
_v5 - Add/modify a station in the fw's sta table.
* ( REPLY_ADD_STA = 0x18 )
* @add_modify: 1: modify existing, 0: add new station
* @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent
...
...
@@ -286,7 +286,7 @@ struct iwl_mvm_keyinfo {
* ADD_STA sets up the table entry for one station, either creating a new
* entry, or modifying a pre-existing one.
*/
struct
iwl_mvm_add_sta_cmd
{
struct
iwl_mvm_add_sta_cmd
_v5
{
u8
add_modify
;
u8
unicast_tx_key_id
;
u8
multicast_tx_key_id
;
...
...
@@ -312,6 +312,57 @@ struct iwl_mvm_add_sta_cmd {
__le32
tfd_queue_msk
;
}
__packed
;
/* ADD_STA_CMD_API_S_VER_5 */
/**
* struct iwl_mvm_add_sta_cmd_v6 - Add / modify a station
* VER_6 of this command is quite similar to VER_5 except
* exclusion of all fields related to the security key installation.
*/
struct
iwl_mvm_add_sta_cmd_v6
{
u8
add_modify
;
u8
reserved1
;
__le16
tid_disable_tx
;
__le32
mac_id_n_color
;
u8
addr
[
ETH_ALEN
];
/* _STA_ID_MODIFY_INFO_API_S_VER_1 */
__le16
reserved2
;
u8
sta_id
;
u8
modify_mask
;
__le16
reserved3
;
__le32
station_flags
;
__le32
station_flags_msk
;
u8
add_immediate_ba_tid
;
u8
remove_immediate_ba_tid
;
__le16
add_immediate_ba_ssn
;
__le16
sleep_tx_count
;
__le16
sleep_state_flags
;
__le16
assoc_id
;
__le16
beamform_flags
;
__le32
tfd_queue_msk
;
}
__packed
;
/* ADD_STA_CMD_API_S_VER_6 */
/**
* struct iwl_mvm_add_sta_key_cmd - add/modify sta key
* ( REPLY_ADD_STA_KEY = 0x17 )
* @sta_id: index of station in uCode's station table
* @key_offset: key offset in key storage
* @key_flags: type %iwl_sta_key_flag
* @key: key material data
* @key2: key material data
* @rx_secur_seq_cnt: RX security sequence counter for the key
* @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection
* @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx
*/
struct
iwl_mvm_add_sta_key_cmd
{
u8
sta_id
;
u8
key_offset
;
__le16
key_flags
;
u8
key
[
16
];
u8
key2
[
16
];
u8
rx_secur_seq_cnt
[
16
];
u8
tkip_rx_tsc_byte2
;
u8
reserved
;
__le16
tkip_rx_ttak
[
5
];
}
__packed
;
/* ADD_MODIFY_STA_KEY_API_S_VER_1 */
/**
* enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command
* @ADD_STA_SUCCESS: operation was executed successfully
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api.h
浏览文件 @
444474dd
...
...
@@ -72,17 +72,17 @@
#include "fw-api-d3.h"
#include "fw-api-bt-coex.h"
/* queue and FIFO numbers by usage */
/* maximal number of Tx queues in any platform */
#define IWL_MVM_MAX_QUEUES 20
/* Tx queue numbers */
enum
{
IWL_MVM_OFFCHANNEL_QUEUE
=
8
,
IWL_MVM_CMD_QUEUE
=
9
,
IWL_MVM_AUX_QUEUE
=
15
,
IWL_MVM_FIRST_AGG_QUEUE
=
16
,
IWL_MVM_NUM_QUEUES
=
20
,
IWL_MVM_LAST_AGG_QUEUE
=
IWL_MVM_NUM_QUEUES
-
1
,
IWL_MVM_CMD_FIFO
=
7
};
#define IWL_MVM_CMD_FIFO 7
#define IWL_MVM_STATION_COUNT 16
/* commands */
...
...
@@ -97,6 +97,7 @@ enum {
DBG_CFG
=
0x9
,
/* station table */
ADD_STA_KEY
=
0x17
,
ADD_STA
=
0x18
,
REMOVE_STA
=
0x19
,
...
...
@@ -114,6 +115,7 @@ enum {
TIME_EVENT_NOTIFICATION
=
0x2a
,
BINDING_CONTEXT_CMD
=
0x2b
,
TIME_QUOTA_CMD
=
0x2c
,
NON_QOS_TX_COUNTER_CMD
=
0x2d
,
LQ_CMD
=
0x4e
,
...
...
@@ -130,6 +132,7 @@ enum {
SCAN_OFFLOAD_COMPLETE
=
0x6D
,
SCAN_OFFLOAD_UPDATE_PROFILES_CMD
=
0x6E
,
SCAN_OFFLOAD_CONFIG_CMD
=
0x6f
,
MATCH_FOUND_NOTIFICATION
=
0xd9
,
/* Phy */
PHY_CONFIGURATION_CMD
=
0x6a
,
...
...
@@ -178,6 +181,7 @@ enum {
BT_COEX_PRIO_TABLE
=
0xcc
,
BT_COEX_PROT_ENV
=
0xcd
,
BT_PROFILE_NOTIFICATION
=
0xce
,
BT_COEX_CI
=
0x5d
,
REPLY_BEACON_FILTERING_CMD
=
0xd2
,
...
...
drivers/net/wireless/iwlwifi/mvm/fw.c
浏览文件 @
444474dd
...
...
@@ -199,7 +199,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
*/
for
(
i
=
0
;
i
<
IWL_MAX_HW_QUEUES
;
i
++
)
{
if
(
i
<
IWL_MVM_FIRST_AGG_QUEUE
&&
i
!=
IWL_MVM_CMD_QUEUE
)
if
(
i
<
mvm
->
first_agg_queue
&&
i
!=
IWL_MVM_CMD_QUEUE
)
mvm
->
queue_to_mac80211
[
i
]
=
i
;
else
mvm
->
queue_to_mac80211
[
i
]
=
IWL_INVALID_MAC80211_QUEUE
;
...
...
@@ -243,7 +243,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
mvm
->
init_ucode_
run
)
if
(
mvm
->
init_ucode_
complete
)
return
0
;
iwl_init_notification_wait
(
&
mvm
->
notif_wait
,
...
...
@@ -264,6 +264,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
if
(
ret
)
goto
error
;
/* Read the NVM only at driver load time, no need to do this twice */
if
(
read_nvm
)
{
/* Read nvm */
ret
=
iwl_nvm_init
(
mvm
);
...
...
@@ -273,6 +274,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
}
}
/* In case we read the NVM from external file, load it to the NIC */
if
(
iwlwifi_mod_params
.
nvm_file
)
iwl_mvm_load_nvm_to_nic
(
mvm
);
ret
=
iwl_nvm_check_version
(
mvm
->
nvm_data
,
mvm
->
trans
);
WARN_ON
(
ret
);
...
...
@@ -310,7 +315,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
ret
=
iwl_wait_notification
(
&
mvm
->
notif_wait
,
&
calib_wait
,
MVM_UCODE_CALIB_TIMEOUT
);
if
(
!
ret
)
mvm
->
init_ucode_
run
=
true
;
mvm
->
init_ucode_
complete
=
true
;
goto
out
;
error:
...
...
@@ -353,8 +358,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if
(
ret
)
return
ret
;
/* If we were in RFKILL during module loading, load init ucode now */
if
(
!
mvm
->
init_ucode_run
)
{
/*
* If we haven't completed the run of the init ucode during
* module loading, load init ucode now
* (for example, if we were in RFKILL)
*/
if
(
!
mvm
->
init_ucode_complete
)
{
ret
=
iwl_run_init_mvm_ucode
(
mvm
,
false
);
if
(
ret
&&
!
iwlmvm_mod_params
.
init_dbg
)
{
IWL_ERR
(
mvm
,
"Failed to run INIT ucode: %d
\n
"
,
ret
);
...
...
@@ -424,6 +433,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto
error
;
}
ret
=
iwl_mvm_power_update_device_mode
(
mvm
);
if
(
ret
)
goto
error
;
IWL_DEBUG_INFO
(
mvm
,
"RT uCode started.
\n
"
);
return
0
;
error:
...
...
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
浏览文件 @
444474dd
...
...
@@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data {
struct
ieee80211_vif
*
vif
;
unsigned
long
available_mac_ids
[
BITS_TO_LONGS
(
NUM_MAC_INDEX_DRIVER
)];
unsigned
long
available_tsf_ids
[
BITS_TO_LONGS
(
NUM_TSF_IDS
)];
unsigned
long
used_hw_queues
[
BITS_TO_LONGS
(
IWL_MVM_
FIRST_AGG_QUEUE
)];
unsigned
long
used_hw_queues
[
BITS_TO_LONGS
(
IWL_MVM_
MAX_QUEUES
)];
enum
iwl_tsf_id
preferred_tsf
;
bool
found_vif
;
};
...
...
@@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
.
preferred_tsf
=
NUM_TSF_IDS
,
.
used_hw_queues
=
{
BIT
(
IWL_MVM_OFFCHANNEL_QUEUE
)
|
BIT
(
IWL_MVM_AUX_QUEUE
)
|
BIT
(
mvm
->
aux_queue
)
|
BIT
(
IWL_MVM_CMD_QUEUE
)
},
.
found_vif
=
false
,
...
...
@@ -242,9 +242,17 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
* that we should share it with another interface.
*/
/* Currently, MAC ID 0 should be used only for the managed vif */
if
(
vif
->
type
!=
NL80211_IFTYPE_STATION
||
vif
->
p2p
)
/* Currently, MAC ID 0 should be used only for the managed/IBSS vif */
switch
(
vif
->
type
)
{
case
NL80211_IFTYPE_ADHOC
:
break
;
case
NL80211_IFTYPE_STATION
:
if
(
!
vif
->
p2p
)
break
;
/* fall through */
default:
__clear_bit
(
0
,
data
.
available_mac_ids
);
}
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
...
...
@@ -302,9 +310,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
/* Find available queues, and allocate them to the ACs */
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
{
u8
queue
=
find_first_zero_bit
(
data
.
used_hw_queues
,
IWL_MVM_FIRST_AGG_QUEUE
);
mvm
->
first_agg_queue
);
if
(
queue
>=
IWL_MVM_FIRST_AGG_QUEUE
)
{
if
(
queue
>=
mvm
->
first_agg_queue
)
{
IWL_ERR
(
mvm
,
"Failed to allocate queue
\n
"
);
ret
=
-
EIO
;
goto
exit_fail
;
...
...
@@ -317,9 +325,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
/* Allocate the CAB queue for softAP and GO interfaces */
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
{
u8
queue
=
find_first_zero_bit
(
data
.
used_hw_queues
,
IWL_MVM_FIRST_AGG_QUEUE
);
mvm
->
first_agg_queue
);
if
(
queue
>=
IWL_MVM_FIRST_AGG_QUEUE
)
{
if
(
queue
>=
mvm
->
first_agg_queue
)
{
IWL_ERR
(
mvm
,
"Failed to allocate cab queue
\n
"
);
ret
=
-
EIO
;
goto
exit_fail
;
...
...
@@ -559,8 +567,12 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
cmd
->
qos_flags
|=
cpu_to_le32
(
MAC_QOS_FLG_UPDATE_EDCA
);
/* Don't use cts to self as the fw doesn't support it currently. */
if
(
vif
->
bss_conf
.
use_cts_prot
)
if
(
vif
->
bss_conf
.
use_cts_prot
)
{
cmd
->
protection_flags
|=
cpu_to_le32
(
MAC_PROT_FLG_TGG_PROTECT
);
if
(
IWL_UCODE_API
(
mvm
->
fw
->
ucode_ver
)
>=
8
)
cmd
->
protection_flags
|=
cpu_to_le32
(
MAC_PROT_FLG_SELF_CTS_EN
);
}
/*
* I think that we should enable these 2 flags regardless the HT PROT
...
...
@@ -712,6 +724,31 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
return
iwl_mvm_mac_ctxt_send_cmd
(
mvm
,
&
cmd
);
}
static
int
iwl_mvm_mac_ctxt_cmd_ibss
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
u32
action
)
{
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
struct
iwl_mac_ctx_cmd
cmd
=
{};
WARN_ON
(
vif
->
type
!=
NL80211_IFTYPE_ADHOC
);
iwl_mvm_mac_ctxt_cmd_common
(
mvm
,
vif
,
&
cmd
,
action
);
cmd
.
filter_flags
=
cpu_to_le32
(
MAC_FILTER_IN_BEACON
|
MAC_FILTER_IN_PROBE_REQUEST
);
/* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
cmd
.
ibss
.
bi
=
cpu_to_le32
(
vif
->
bss_conf
.
beacon_int
);
cmd
.
ibss
.
bi_reciprocal
=
cpu_to_le32
(
iwl_mvm_reciprocal
(
vif
->
bss_conf
.
beacon_int
));
/* TODO: Assumes that the beacon id == mac context id */
cmd
.
ibss
.
beacon_template
=
cpu_to_le32
(
mvmvif
->
id
);
return
iwl_mvm_mac_ctxt_send_cmd
(
mvm
,
&
cmd
);
}
struct
iwl_mvm_go_iterator_data
{
bool
go_active
;
};
...
...
@@ -721,7 +758,8 @@ static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif)
struct
iwl_mvm_go_iterator_data
*
data
=
_data
;
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
if
(
vif
->
type
==
NL80211_IFTYPE_AP
&&
vif
->
p2p
&&
mvmvif
->
ap_active
)
if
(
vif
->
type
==
NL80211_IFTYPE_AP
&&
vif
->
p2p
&&
mvmvif
->
ap_ibss_active
)
data
->
go_active
=
true
;
}
...
...
@@ -833,9 +871,10 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
cpu_to_le32
(
iwl_mvm_mac80211_idx_to_hwrate
(
rate
));
/* Set up TX beacon command fields */
iwl_mvm_mac_ctxt_set_tim
(
mvm
,
&
beacon_cmd
,
beacon
->
data
,
beacon_skb_len
);
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
iwl_mvm_mac_ctxt_set_tim
(
mvm
,
&
beacon_cmd
,
beacon
->
data
,
beacon_skb_len
);
/* Submit command */
cmd
.
len
[
0
]
=
sizeof
(
beacon_cmd
);
...
...
@@ -848,14 +887,15 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
return
iwl_mvm_send_cmd
(
mvm
,
&
cmd
);
}
/* The beacon template for the AP/GO
context
has changed and needs update */
/* The beacon template for the AP/GO
/IBSS
has changed and needs update */
int
iwl_mvm_mac_ctxt_beacon_changed
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
struct
sk_buff
*
beacon
;
int
ret
;
WARN_ON
(
vif
->
type
!=
NL80211_IFTYPE_AP
);
WARN_ON
(
vif
->
type
!=
NL80211_IFTYPE_AP
&&
vif
->
type
!=
NL80211_IFTYPE_ADHOC
);
beacon
=
ieee80211_beacon_get
(
mvm
->
hw
,
vif
);
if
(
!
beacon
)
...
...
@@ -1018,6 +1058,8 @@ static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return
iwl_mvm_mac_ctxt_cmd_listener
(
mvm
,
vif
,
action
);
case
NL80211_IFTYPE_P2P_DEVICE
:
return
iwl_mvm_mac_ctxt_cmd_p2p_device
(
mvm
,
vif
,
action
);
case
NL80211_IFTYPE_ADHOC
:
return
iwl_mvm_mac_ctxt_cmd_ibss
(
mvm
,
vif
,
action
);
default:
break
;
}
...
...
@@ -1038,6 +1080,9 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
if
(
ret
)
return
ret
;
/* will only do anything at resume from D3 time */
iwl_mvm_set_last_nonqos_seq
(
mvm
,
vif
);
mvmvif
->
uploaded
=
true
;
return
0
;
}
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
浏览文件 @
444474dd
...
...
@@ -77,6 +77,7 @@
#include "iwl-eeprom-parse.h"
#include "fw-api-scan.h"
#include "iwl-phy-db.h"
#include "testmode.h"
static
const
struct
ieee80211_iface_limit
iwl_mvm_limits
[]
=
{
{
...
...
@@ -138,6 +139,14 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
}
}
static
int
iwl_mvm_max_scan_ie_len
(
struct
iwl_mvm
*
mvm
)
{
/* we create the 802.11 header and SSID element */
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID
)
return
mvm
->
fw
->
ucode_capa
.
max_probe_length
-
24
-
2
;
return
mvm
->
fw
->
ucode_capa
.
max_probe_length
-
24
-
34
;
}
int
iwl_mvm_mac_setup_register
(
struct
iwl_mvm
*
mvm
)
{
struct
ieee80211_hw
*
hw
=
mvm
->
hw
;
...
...
@@ -158,7 +167,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IEEE80211_HW_SUPPORTS_STATIC_SMPS
|
IEEE80211_HW_SUPPORTS_UAPSD
;
hw
->
queues
=
IWL_MVM_FIRST_AGG_QUEUE
;
hw
->
queues
=
mvm
->
first_agg_queue
;
hw
->
offchannel_tx_hw_queue
=
IWL_MVM_OFFCHANNEL_QUEUE
;
hw
->
rate_control_algorithm
=
"iwl-mvm-rs"
;
...
...
@@ -181,6 +190,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
BIT
(
NL80211_IFTYPE_P2P_GO
)
|
BIT
(
NL80211_IFTYPE_P2P_DEVICE
);
/* IBSS has bugs in older versions */
if
(
IWL_UCODE_API
(
mvm
->
fw
->
ucode_ver
)
>=
8
)
hw
->
wiphy
->
interface_modes
|=
BIT
(
NL80211_IFTYPE_ADHOC
);
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_CUSTOM_REGULATORY
|
WIPHY_FLAG_DISABLE_BEACON_HINTS
|
WIPHY_FLAG_IBSS_RSN
;
...
...
@@ -212,9 +225,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
iwl_mvm_reset_phy_ctxts
(
mvm
);
/* we create the 802.11 header and a max-length SSID element */
hw
->
wiphy
->
max_scan_ie_len
=
mvm
->
fw
->
ucode_capa
.
max_probe_length
-
24
-
34
;
hw
->
wiphy
->
max_scan_ie_len
=
iwl_mvm_max_scan_ie_len
(
mvm
);
hw
->
wiphy
->
max_scan_ssids
=
PROBE_OPTION_MAX
;
if
(
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
)
...
...
@@ -231,6 +243,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
else
hw
->
wiphy
->
flags
&=
~
WIPHY_FLAG_PS_ON_BY_DEFAULT
;
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_SCHED_SCAN
)
{
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
hw
->
wiphy
->
max_sched_scan_ssids
=
PROBE_OPTION_MAX
;
hw
->
wiphy
->
max_match_sets
=
IWL_SCAN_MAX_PROFILES
;
/* we create the 802.11 header and zero length SSID IE. */
hw
->
wiphy
->
max_sched_scan_ie_len
=
SCAN_OFFLOAD_PROBE_REQ_SIZE
-
24
-
2
;
}
hw
->
wiphy
->
features
|=
NL80211_FEATURE_P2P_GO_CTWIN
|
NL80211_FEATURE_P2P_GO_OPPPS
;
...
...
@@ -548,7 +569,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
* In short: there's not much we can do at this point, other than
* allocating resources :)
*/
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
{
if
(
vif
->
type
==
NL80211_IFTYPE_AP
||
vif
->
type
==
NL80211_IFTYPE_ADHOC
)
{
u32
qmask
=
iwl_mvm_mac_get_queues_mask
(
mvm
,
vif
);
ret
=
iwl_mvm_allocate_int_sta
(
mvm
,
&
mvmvif
->
bcast_sta
,
qmask
);
...
...
@@ -698,7 +720,14 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
* For AP/GO interface, the tear down of the resources allocated to the
* interface is be handled as part of the stop_ap flow.
*/
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
{
if
(
vif
->
type
==
NL80211_IFTYPE_AP
||
vif
->
type
==
NL80211_IFTYPE_ADHOC
)
{
#ifdef CONFIG_NL80211_TESTMODE
if
(
vif
==
mvm
->
noa_vif
)
{
mvm
->
noa_vif
=
NULL
;
mvm
->
noa_duration
=
0
;
}
#endif
iwl_mvm_dealloc_int_sta
(
mvm
,
&
mvmvif
->
bcast_sta
);
goto
out_release
;
}
...
...
@@ -796,6 +825,27 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
return
;
}
iwl_mvm_configure_mcast_filter
(
mvm
,
vif
);
if
(
test_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
))
{
/*
* If we're restarting then the firmware will
* obviously have lost synchronisation with
* the AP. It will attempt to synchronise by
* itself, but we can make it more reliable by
* scheduling a session protection time event.
*
* The firmware needs to receive a beacon to
* catch up with synchronisation, use 110% of
* the beacon interval.
*
* Set a large maximum delay to allow for more
* than a single interface.
*/
u32
dur
=
(
11
*
vif
->
bss_conf
.
beacon_int
)
/
10
;
iwl_mvm_protect_session
(
mvm
,
vif
,
dur
,
dur
,
5
*
dur
);
}
}
else
if
(
mvmvif
->
ap_sta_id
!=
IWL_MVM_STATION_COUNT
)
{
/* remove AP station now that the MAC is unassoc */
ret
=
iwl_mvm_rm_sta_id
(
mvm
,
vif
,
mvmvif
->
ap_sta_id
);
...
...
@@ -819,7 +869,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
if
(
ret
)
IWL_ERR
(
mvm
,
"failed to update power mode
\n
"
);
}
iwl_mvm_bt_coex_vif_
assoc
(
mvm
,
vif
);
iwl_mvm_bt_coex_vif_
change
(
mvm
);
}
else
if
(
changes
&
BSS_CHANGED_BEACON_INFO
)
{
/*
* We received a beacon _after_ association so
...
...
@@ -848,7 +898,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
}
}
static
int
iwl_mvm_start_ap
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
static
int
iwl_mvm_start_ap_ibss
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
...
...
@@ -871,7 +922,7 @@ static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
if
(
ret
)
goto
out_remove
;
mvmvif
->
ap_active
=
true
;
mvmvif
->
ap_
ibss_
active
=
true
;
/* Send the bcast station. At this stage the TBTT and DTIM time events
* are added and applied to the scheduler */
...
...
@@ -883,10 +934,12 @@ static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
if
(
ret
)
goto
out_rm_bcast
;
/* Need to update the P2P Device MAC */
/* Need to update the P2P Device MAC
(only GO, IBSS is single vif)
*/
if
(
vif
->
p2p
&&
mvm
->
p2p_device_vif
)
iwl_mvm_mac_ctxt_changed
(
mvm
,
mvm
->
p2p_device_vif
);
iwl_mvm_bt_coex_vif_change
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
return
0
;
...
...
@@ -901,7 +954,8 @@ static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return
ret
;
}
static
void
iwl_mvm_stop_ap
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
static
void
iwl_mvm_stop_ap_ibss
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
...
...
@@ -910,9 +964,11 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mutex_lock
(
&
mvm
->
mutex
);
mvmvif
->
ap_active
=
false
;
mvmvif
->
ap_ibss_active
=
false
;
iwl_mvm_bt_coex_vif_change
(
mvm
);
/* Need to update the P2P Device MAC */
/* Need to update the P2P Device MAC
(only GO, IBSS is single vif)
*/
if
(
vif
->
p2p
&&
mvm
->
p2p_device_vif
)
iwl_mvm_mac_ctxt_changed
(
mvm
,
mvm
->
p2p_device_vif
);
...
...
@@ -924,10 +980,11 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mutex_unlock
(
&
mvm
->
mutex
);
}
static
void
iwl_mvm_bss_info_changed_ap
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_bss_conf
*
bss_conf
,
u32
changes
)
static
void
iwl_mvm_bss_info_changed_ap_ibss
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_bss_conf
*
bss_conf
,
u32
changes
)
{
/* Need to send a new beacon template to the FW */
if
(
changes
&
BSS_CHANGED_BEACON
)
{
...
...
@@ -950,7 +1007,8 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
iwl_mvm_bss_info_changed_station
(
mvm
,
vif
,
bss_conf
,
changes
);
break
;
case
NL80211_IFTYPE_AP
:
iwl_mvm_bss_info_changed_ap
(
mvm
,
vif
,
bss_conf
,
changes
);
case
NL80211_IFTYPE_ADHOC
:
iwl_mvm_bss_info_changed_ap_ibss
(
mvm
,
vif
,
bss_conf
,
changes
);
break
;
default:
/* shouldn't happen */
...
...
@@ -1163,7 +1221,54 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
mutex_lock
(
&
mvm
->
mutex
);
/* Try really hard to protect the session and hear a beacon */
iwl_mvm_protect_session
(
mvm
,
vif
,
duration
,
min_duration
);
iwl_mvm_protect_session
(
mvm
,
vif
,
duration
,
min_duration
,
500
);
mutex_unlock
(
&
mvm
->
mutex
);
}
static
int
iwl_mvm_mac_sched_scan_start
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_sched_scan_request
*
req
,
struct
ieee80211_sched_scan_ies
*
ies
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
int
ret
;
mutex_lock
(
&
mvm
->
mutex
);
if
(
mvm
->
scan_status
!=
IWL_MVM_SCAN_NONE
)
{
IWL_DEBUG_SCAN
(
mvm
,
"SCHED SCAN request during internal scan - abort
\n
"
);
ret
=
-
EBUSY
;
goto
out
;
}
mvm
->
scan_status
=
IWL_MVM_SCAN_SCHED
;
ret
=
iwl_mvm_config_sched_scan
(
mvm
,
vif
,
req
,
ies
);
if
(
ret
)
goto
err
;
ret
=
iwl_mvm_config_sched_scan_profiles
(
mvm
,
req
);
if
(
ret
)
goto
err
;
ret
=
iwl_mvm_sched_scan_start
(
mvm
,
req
);
if
(
!
ret
)
goto
out
;
err:
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
out:
mutex_unlock
(
&
mvm
->
mutex
);
return
ret
;
}
static
void
iwl_mvm_mac_sched_scan_stop
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
mutex_lock
(
&
mvm
->
mutex
);
iwl_mvm_sched_scan_stop
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
}
...
...
@@ -1207,8 +1312,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
switch
(
cmd
)
{
case
SET_KEY
:
if
(
vif
->
type
==
NL80211_IFTYPE_AP
&&
!
sta
)
{
/* GTK on AP interface is a TX-only key, return 0 */
if
((
vif
->
type
==
NL80211_IFTYPE_ADHOC
||
vif
->
type
==
NL80211_IFTYPE_AP
)
&&
!
sta
)
{
/*
* GTK on AP interface is a TX-only key, return 0;
* on IBSS they're per-station and because we're lazy
* we don't support them for RX, so do the same.
*/
ret
=
0
;
key
->
hw_key_idx
=
STA_KEY_IDX_INVALID
;
break
;
...
...
@@ -1252,6 +1362,9 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
if
(
keyconf
->
hw_key_idx
==
STA_KEY_IDX_INVALID
)
return
;
iwl_mvm_update_tkip_key
(
mvm
,
vif
,
keyconf
,
sta
,
iv32
,
phase1key
);
}
...
...
@@ -1445,6 +1558,7 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
iwl_mvm_phy_ctxt_changed
(
mvm
,
phy_ctxt
,
&
ctx
->
def
,
ctx
->
rx_chains_static
,
ctx
->
rx_chains_dynamic
);
iwl_mvm_bt_coex_vif_change
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
}
...
...
@@ -1464,14 +1578,14 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
switch
(
vif
->
type
)
{
case
NL80211_IFTYPE_AP
:
case
NL80211_IFTYPE_ADHOC
:
/*
* The AP binding flow is handled as part of the start_ap flow
* (in bss_info_changed).
* (in bss_info_changed)
, similarly for IBSS
.
*/
ret
=
0
;
goto
out_unlock
;
case
NL80211_IFTYPE_STATION
:
case
NL80211_IFTYPE_ADHOC
:
case
NL80211_IFTYPE_MONITOR
:
break
;
default:
...
...
@@ -1517,10 +1631,10 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
iwl_mvm_remove_time_event
(
mvm
,
mvmvif
,
&
mvmvif
->
time_event_data
);
if
(
vif
->
type
==
NL80211_IFTYPE_AP
)
goto
out_unlock
;
switch
(
vif
->
type
)
{
case
NL80211_IFTYPE_AP
:
case
NL80211_IFTYPE_ADHOC
:
goto
out_unlock
;
case
NL80211_IFTYPE_MONITOR
:
mvmvif
->
monitor_active
=
false
;
iwl_mvm_update_quotas
(
mvm
,
NULL
);
...
...
@@ -1550,14 +1664,72 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
return
iwl_mvm_mac_ctxt_beacon_changed
(
mvm
,
mvm_sta
->
vif
);
}
static
void
iwl_mvm_mac_rssi_callback
(
struct
ieee80211_hw
*
hw
,
#ifdef CONFIG_NL80211_TESTMODE
static
const
struct
nla_policy
iwl_mvm_tm_policy
[
IWL_MVM_TM_ATTR_MAX
+
1
]
=
{
[
IWL_MVM_TM_ATTR_CMD
]
=
{
.
type
=
NLA_U32
},
[
IWL_MVM_TM_ATTR_NOA_DURATION
]
=
{
.
type
=
NLA_U32
},
[
IWL_MVM_TM_ATTR_BEACON_FILTER_STATE
]
=
{
.
type
=
NLA_U32
},
};
static
int
__iwl_mvm_mac_testmode_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
)
void
*
data
,
int
len
)
{
struct
nlattr
*
tb
[
IWL_MVM_TM_ATTR_MAX
+
1
];
int
err
;
u32
noa_duration
;
err
=
nla_parse
(
tb
,
IWL_MVM_TM_ATTR_MAX
,
data
,
len
,
iwl_mvm_tm_policy
);
if
(
err
)
return
err
;
if
(
!
tb
[
IWL_MVM_TM_ATTR_CMD
])
return
-
EINVAL
;
switch
(
nla_get_u32
(
tb
[
IWL_MVM_TM_ATTR_CMD
]))
{
case
IWL_MVM_TM_CMD_SET_NOA
:
if
(
!
vif
||
vif
->
type
!=
NL80211_IFTYPE_AP
||
!
vif
->
p2p
||
!
vif
->
bss_conf
.
enable_beacon
||
!
tb
[
IWL_MVM_TM_ATTR_NOA_DURATION
])
return
-
EINVAL
;
noa_duration
=
nla_get_u32
(
tb
[
IWL_MVM_TM_ATTR_NOA_DURATION
]);
if
(
noa_duration
>=
vif
->
bss_conf
.
beacon_int
)
return
-
EINVAL
;
mvm
->
noa_duration
=
noa_duration
;
mvm
->
noa_vif
=
vif
;
return
iwl_mvm_update_quotas
(
mvm
,
NULL
);
case
IWL_MVM_TM_CMD_SET_BEACON_FILTER
:
/* must be associated client vif - ignore authorized */
if
(
!
vif
||
vif
->
type
!=
NL80211_IFTYPE_STATION
||
!
vif
->
bss_conf
.
assoc
||
!
vif
->
bss_conf
.
dtim_period
||
!
tb
[
IWL_MVM_TM_ATTR_BEACON_FILTER_STATE
])
return
-
EINVAL
;
if
(
nla_get_u32
(
tb
[
IWL_MVM_TM_ATTR_BEACON_FILTER_STATE
]))
return
iwl_mvm_enable_beacon_filter
(
mvm
,
vif
);
return
iwl_mvm_disable_beacon_filter
(
mvm
,
vif
);
}
return
-
EOPNOTSUPP
;
}
static
int
iwl_mvm_mac_testmode_cmd
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
void
*
data
,
int
len
)
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
int
err
;
iwl_mvm_bt_rssi_event
(
mvm
,
vif
,
rssi_event
);
mutex_lock
(
&
mvm
->
mutex
);
err
=
__iwl_mvm_mac_testmode_cmd
(
mvm
,
vif
,
data
,
len
);
mutex_unlock
(
&
mvm
->
mutex
);
return
err
;
}
#endif
struct
ieee80211_ops
iwl_mvm_hw_ops
=
{
.
tx
=
iwl_mvm_mac_tx
,
...
...
@@ -1578,23 +1750,27 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
.
set_rts_threshold
=
iwl_mvm_mac_set_rts_threshold
,
.
conf_tx
=
iwl_mvm_mac_conf_tx
,
.
mgd_prepare_tx
=
iwl_mvm_mac_mgd_prepare_tx
,
.
sched_scan_start
=
iwl_mvm_mac_sched_scan_start
,
.
sched_scan_stop
=
iwl_mvm_mac_sched_scan_stop
,
.
set_key
=
iwl_mvm_mac_set_key
,
.
update_tkip_key
=
iwl_mvm_mac_update_tkip_key
,
.
remain_on_channel
=
iwl_mvm_roc
,
.
cancel_remain_on_channel
=
iwl_mvm_cancel_roc
,
.
rssi_callback
=
iwl_mvm_mac_rssi_callback
,
.
add_chanctx
=
iwl_mvm_add_chanctx
,
.
remove_chanctx
=
iwl_mvm_remove_chanctx
,
.
change_chanctx
=
iwl_mvm_change_chanctx
,
.
assign_vif_chanctx
=
iwl_mvm_assign_vif_chanctx
,
.
unassign_vif_chanctx
=
iwl_mvm_unassign_vif_chanctx
,
.
start_ap
=
iwl_mvm_start_ap
,
.
stop_ap
=
iwl_mvm_stop_ap
,
.
start_ap
=
iwl_mvm_start_ap_ibss
,
.
stop_ap
=
iwl_mvm_stop_ap_ibss
,
.
join_ibss
=
iwl_mvm_start_ap_ibss
,
.
leave_ibss
=
iwl_mvm_stop_ap_ibss
,
.
set_tim
=
iwl_mvm_set_tim
,
CFG80211_TESTMODE_CMD
(
iwl_mvm_mac_testmode_cmd
)
#ifdef CONFIG_PM_SLEEP
/* look at d3.c */
.
suspend
=
iwl_mvm_suspend
,
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
浏览文件 @
444474dd
...
...
@@ -162,6 +162,7 @@ enum iwl_power_scheme {
struct
iwl_mvm_power_ops
{
int
(
*
power_update_mode
)(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
int
(
*
power_update_device_mode
)(
struct
iwl_mvm
*
mvm
);
int
(
*
power_disable
)(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
int
(
*
power_dbgfs_read
)(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
...
...
@@ -241,12 +242,18 @@ enum iwl_mvm_smps_type_request {
* @last_beacon_signal: last beacon rssi signal in dbm
* @ave_beacon_signal: average beacon signal
* @last_cqm_event: rssi of the last cqm event
* @bt_coex_min_thold: minimum threshold for BT coex
* @bt_coex_max_thold: maximum threshold for BT coex
* @last_bt_coex_event: rssi of the last BT coex event
*/
struct
iwl_mvm_vif_bf_data
{
bool
bf_enabled
;
bool
ba_enabled
;
s8
ave_beacon_signal
;
s8
last_cqm_event
;
s8
bt_coex_min_thold
;
s8
bt_coex_max_thold
;
s8
last_bt_coex_event
;
};
/**
...
...
@@ -255,8 +262,8 @@ struct iwl_mvm_vif_bf_data {
* @color: to solve races upon MAC addition and removal
* @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
* @uploaded: indicates the MAC context has been added to the device
* @ap_
active: indicates that ap context is configured,
and that the interface
*
should get quota etc.
* @ap_
ibss_active: indicates that AP/IBSS is configured
and that the interface
*
should get quota etc.
* @monitor_active: indicates that monitor context is configured, and that the
* interface should get quota etc.
* @queue_params: QoS params for this MAC
...
...
@@ -272,7 +279,7 @@ struct iwl_mvm_vif {
u8
ap_sta_id
;
bool
uploaded
;
bool
ap_active
;
bool
ap_
ibss_
active
;
bool
monitor_active
;
struct
iwl_mvm_vif_bf_data
bf_data
;
...
...
@@ -306,6 +313,9 @@ struct iwl_mvm_vif {
int
tx_key_idx
;
bool
seqno_valid
;
u16
seqno
;
#if IS_ENABLED(CONFIG_IPV6)
/* IPv6 addresses for WoWLAN */
struct
in6_addr
target_ipv6_addrs
[
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX
];
...
...
@@ -333,6 +343,7 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
enum
iwl_scan_status
{
IWL_MVM_SCAN_NONE
,
IWL_MVM_SCAN_OS
,
IWL_MVM_SCAN_SCHED
,
};
/**
...
...
@@ -434,7 +445,7 @@ struct iwl_mvm {
enum
iwl_ucode_type
cur_ucode
;
bool
ucode_loaded
;
bool
init_ucode_
run
;
bool
init_ucode_
complete
;
u32
error_event_table
;
u32
log_event_table
;
...
...
@@ -470,6 +481,9 @@ struct iwl_mvm {
enum
iwl_scan_status
scan_status
;
struct
iwl_scan_cmd
*
scan_cmd
;
/* rx chain antennas set through debugfs for the scan command */
u8
scan_rx_ant
;
/* Internal station */
struct
iwl_mvm_int_sta
aux_sta
;
...
...
@@ -479,7 +493,8 @@ struct iwl_mvm {
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct
dentry
*
debugfs_dir
;
u32
dbgfs_sram_offset
,
dbgfs_sram_len
;
bool
prevent_power_down_d3
;
bool
disable_power_off
;
bool
disable_power_off_d3
;
#endif
struct
iwl_mvm_phy_ctxt
phy_ctxts
[
NUM_PHY_CTX
];
...
...
@@ -523,12 +538,23 @@ struct iwl_mvm {
/* BT-Coex */
u8
bt_kill_msk
;
struct
iwl_bt_coex_profile_notif
last_bt_notif
;
struct
iwl_bt_coex_ci_cmd
last_bt_ci_cmd
;
/* Thermal Throttling and CTkill */
struct
iwl_mvm_tt_mgmt
thermal_throttle
;
s32
temperature
;
/* Celsius */
const
struct
iwl_mvm_power_ops
*
pm_ops
;
#ifdef CONFIG_NL80211_TESTMODE
u32
noa_duration
;
struct
ieee80211_vif
*
noa_vif
;
#endif
/* Tx queues */
u8
aux_queue
;
u8
first_agg_queue
;
u8
last_agg_queue
;
};
/* Extract MVM priv from op_mode and _hw */
...
...
@@ -570,6 +596,9 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm);
/* Utils */
int
iwl_mvm_legacy_rate_to_mac80211_idx
(
u32
rate_n_flags
,
enum
ieee80211_band
band
);
void
iwl_mvm_hwrate_to_tx_rate
(
u32
rate_n_flags
,
enum
ieee80211_band
band
,
struct
ieee80211_tx_rate
*
r
);
u8
iwl_mvm_mac80211_idx_to_hwrate
(
int
rate_idx
);
void
iwl_mvm_dump_nic_error_log
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_dump_sram
(
struct
iwl_mvm
*
mvm
);
...
...
@@ -608,6 +637,7 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
/* NVM */
int
iwl_nvm_init
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_load_nvm_to_nic
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_up
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_load_d3_fw
(
struct
iwl_mvm
*
mvm
);
...
...
@@ -682,6 +712,23 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct
iwl_device_cmd
*
cmd
);
void
iwl_mvm_cancel_scan
(
struct
iwl_mvm
*
mvm
);
/* Scheduled scan */
int
iwl_mvm_rx_scan_offload_complete_notif
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
int
iwl_mvm_config_sched_scan
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_sched_scan_request
*
req
,
struct
ieee80211_sched_scan_ies
*
ies
);
int
iwl_mvm_config_sched_scan_profiles
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
);
int
iwl_mvm_sched_scan_start
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
);
void
iwl_mvm_sched_scan_stop
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_rx_sched_scan_results
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
/* MVM debugfs */
#ifdef CONFIG_IWLWIFI_DEBUGFS
int
iwl_mvm_dbgfs_register
(
struct
iwl_mvm
*
mvm
,
struct
dentry
*
dbgfs_dir
);
...
...
@@ -720,6 +767,13 @@ static inline int iwl_mvm_power_disable(struct iwl_mvm *mvm,
return
mvm
->
pm_ops
->
power_disable
(
mvm
,
vif
);
}
static
inline
int
iwl_mvm_power_update_device_mode
(
struct
iwl_mvm
*
mvm
)
{
if
(
mvm
->
pm_ops
->
power_update_device_mode
)
return
mvm
->
pm_ops
->
power_update_device_mode
(
mvm
);
return
0
;
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
static
inline
int
iwl_mvm_power_dbgfs_read
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
...
...
@@ -745,6 +799,15 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
void
iwl_mvm_set_default_unicast_key
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
int
idx
);
extern
const
struct
file_operations
iwl_dbgfs_d3_test_ops
;
#ifdef CONFIG_PM_SLEEP
void
iwl_mvm_set_last_nonqos_seq
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
#else
static
inline
void
iwl_mvm_set_last_nonqos_seq
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
}
#endif
/* BT Coex */
int
iwl_send_bt_prio_tbl
(
struct
iwl_mvm
*
mvm
);
...
...
@@ -754,7 +817,20 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct
iwl_device_cmd
*
cmd
);
void
iwl_mvm_bt_rssi_event
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
);
void
iwl_mvm_bt_coex_vif_assoc
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
);
void
iwl_mvm_bt_coex_vif_change
(
struct
iwl_mvm
*
mvm
);
u16
iwl_mvm_bt_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
);
enum
iwl_bt_kill_msk
{
BT_KILL_MSK_DEFAULT
,
BT_KILL_MSK_SCO_HID_A2DP
,
BT_KILL_MSK_REDUCED_TXPOW
,
BT_KILL_MSK_MAX
,
};
extern
const
u32
iwl_bt_ack_kill_msk
[
BT_KILL_MSK_MAX
];
extern
const
u32
iwl_bt_cts_kill_msk
[
BT_KILL_MSK_MAX
];
/* beacon filtering */
#ifdef CONFIG_IWLWIFI_DEBUGFS
...
...
drivers/net/wireless/iwlwifi/mvm/nvm.c
浏览文件 @
444474dd
...
...
@@ -77,7 +77,7 @@ static const int nvm_to_read[] = {
/* Default NVM size to read */
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
#define IWL_MAX_NVM_SECTION_SIZE
6
000
#define IWL_MAX_NVM_SECTION_SIZE
7
000
#define NVM_WRITE_OPCODE 1
#define NVM_READ_OPCODE 0
...
...
@@ -259,6 +259,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
#define MAX_NVM_FILE_LEN 16384
/*
* Reads external NVM from a file into mvm->nvm_sections
*
* HOW TO CREATE THE NVM FILE FORMAT:
* ------------------------------
* 1. create hex file, format:
...
...
@@ -277,20 +279,23 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
*
* 4. save as "iNVM_xxx.bin" under /lib/firmware
*/
static
int
iwl_mvm_
lo
ad_external_nvm
(
struct
iwl_mvm
*
mvm
)
static
int
iwl_mvm_
re
ad_external_nvm
(
struct
iwl_mvm
*
mvm
)
{
int
ret
,
section_id
,
section_size
;
int
ret
,
section_size
;
u16
section_id
;
const
struct
firmware
*
fw_entry
;
const
struct
{
__le16
word1
;
__le16
word2
;
u8
data
[];
}
*
file_sec
;
const
u8
*
eof
;
const
u8
*
eof
,
*
temp
;
#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
#define NVM_WORD2_ID(x) (x >> 12)
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
"Read from external NVM
\n
"
);
/*
* Obtain NVM image via request_firmware. Since we already used
* request_firmware_nowait() for the firmware binary load and only
...
...
@@ -362,12 +367,18 @@ static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
break
;
}
ret
=
iwl_nvm_write_section
(
mvm
,
section_id
,
file_sec
->
data
,
section_size
);
if
(
ret
<
0
)
{
IWL_ERR
(
mvm
,
"iwl_mvm_send_cmd failed: %d
\n
"
,
ret
);
temp
=
kmemdup
(
file_sec
->
data
,
section_size
,
GFP_KERNEL
);
if
(
!
temp
)
{
ret
=
-
ENOMEM
;
break
;
}
if
(
WARN_ON
(
section_id
>=
NVM_NUM_OF_SECTIONS
))
{
IWL_ERR
(
mvm
,
"Invalid NVM section ID
\n
"
);
ret
=
-
EINVAL
;
break
;
}
mvm
->
nvm_sections
[
section_id
].
data
=
temp
;
mvm
->
nvm_sections
[
section_id
].
length
=
section_size
;
/* advance to the next section */
file_sec
=
(
void
*
)(
file_sec
->
data
+
section_size
);
...
...
@@ -377,6 +388,28 @@ static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
return
ret
;
}
/* Loads the NVM data stored in mvm->nvm_sections into the NIC */
int
iwl_mvm_load_nvm_to_nic
(
struct
iwl_mvm
*
mvm
)
{
int
i
,
ret
;
u16
section_id
;
struct
iwl_nvm_section
*
sections
=
mvm
->
nvm_sections
;
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
"'Write to NVM
\n
"
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
nvm_to_read
);
i
++
)
{
section_id
=
nvm_to_read
[
i
];
ret
=
iwl_nvm_write_section
(
mvm
,
section_id
,
sections
[
section_id
].
data
,
sections
[
section_id
].
length
);
if
(
ret
<
0
)
{
IWL_ERR
(
mvm
,
"iwl_mvm_send_cmd failed: %d
\n
"
,
ret
);
break
;
}
}
return
ret
;
}
int
iwl_nvm_init
(
struct
iwl_mvm
*
mvm
)
{
int
ret
,
i
,
section
;
...
...
@@ -385,36 +418,36 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
/* load external NVM if configured */
if
(
iwlwifi_mod_params
.
nvm_file
)
{
/* move to External NVM flow */
ret
=
iwl_mvm_
lo
ad_external_nvm
(
mvm
);
ret
=
iwl_mvm_
re
ad_external_nvm
(
mvm
);
if
(
ret
)
return
ret
;
}
/* Read From FW NVM */
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
"Read from NVM
\n
"
);
/* TODO: find correct NVM max size for a section */
nvm_buffer
=
kmalloc
(
mvm
->
cfg
->
base_params
->
eeprom_size
,
GFP_KERNEL
);
if
(
!
nvm_buffer
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
nvm_to_read
);
i
++
)
{
section
=
nvm_to_read
[
i
];
/* we override the constness for initial read */
ret
=
iwl_nvm_read_section
(
mvm
,
section
,
nvm_buffer
);
if
(
ret
<
0
)
break
;
temp
=
kmemdup
(
nvm_buffer
,
ret
,
GFP_KERNEL
);
if
(
!
temp
)
{
ret
=
-
ENOMEM
;
break
;
}
else
{
/* Read From FW NVM */
IWL_DEBUG_EEPROM
(
mvm
->
trans
->
dev
,
"Read from NVM
\n
"
);
/* TODO: find correct NVM max size for a section */
nvm_buffer
=
kmalloc
(
mvm
->
cfg
->
base_params
->
eeprom_size
,
GFP_KERNEL
);
if
(
!
nvm_buffer
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
nvm_to_read
);
i
++
)
{
section
=
nvm_to_read
[
i
];
/* we override the constness for initial read */
ret
=
iwl_nvm_read_section
(
mvm
,
section
,
nvm_buffer
);
if
(
ret
<
0
)
break
;
temp
=
kmemdup
(
nvm_buffer
,
ret
,
GFP_KERNEL
);
if
(
!
temp
)
{
ret
=
-
ENOMEM
;
break
;
}
mvm
->
nvm_sections
[
section
].
data
=
temp
;
mvm
->
nvm_sections
[
section
].
length
=
ret
;
}
mvm
->
nvm_sections
[
section
].
data
=
temp
;
mvm
->
nvm_sections
[
section
].
length
=
ret
;
kfree
(
nvm_buffer
);
if
(
ret
<
0
)
return
ret
;
}
kfree
(
nvm_buffer
);
if
(
ret
<
0
)
return
ret
;
mvm
->
nvm_data
=
iwl_parse_nvm_sections
(
mvm
);
if
(
!
mvm
->
nvm_data
)
...
...
drivers/net/wireless/iwlwifi/mvm/ops.c
浏览文件 @
444474dd
...
...
@@ -224,6 +224,10 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER
(
SCAN_REQUEST_CMD
,
iwl_mvm_rx_scan_response
,
false
),
RX_HANDLER
(
SCAN_COMPLETE_NOTIFICATION
,
iwl_mvm_rx_scan_complete
,
false
),
RX_HANDLER
(
SCAN_OFFLOAD_COMPLETE
,
iwl_mvm_rx_scan_offload_complete_notif
,
false
),
RX_HANDLER
(
MATCH_FOUND_NOTIFICATION
,
iwl_mvm_rx_sched_scan_results
,
false
),
RX_HANDLER
(
RADIO_VERSION_NOTIFICATION
,
iwl_mvm_rx_radio_ver
,
false
),
RX_HANDLER
(
CARD_STATE_NOTIFICATION
,
iwl_mvm_rx_card_state_notif
,
false
),
...
...
@@ -249,6 +253,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD
(
TIME_EVENT_NOTIFICATION
),
CMD
(
BINDING_CONTEXT_CMD
),
CMD
(
TIME_QUOTA_CMD
),
CMD
(
NON_QOS_TX_COUNTER_CMD
),
CMD
(
RADIO_VERSION_NOTIFICATION
),
CMD
(
SCAN_REQUEST_CMD
),
CMD
(
SCAN_ABORT_CMD
),
...
...
@@ -260,10 +265,12 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD
(
CALIB_RES_NOTIF_PHY_DB
),
CMD
(
SET_CALIB_DEFAULT_CMD
),
CMD
(
CALIBRATION_COMPLETE_NOTIFICATION
),
CMD
(
ADD_STA_KEY
),
CMD
(
ADD_STA
),
CMD
(
REMOVE_STA
),
CMD
(
LQ_CMD
),
CMD
(
SCAN_OFFLOAD_CONFIG_CMD
),
CMD
(
MATCH_FOUND_NOTIFICATION
),
CMD
(
SCAN_OFFLOAD_REQUEST_CMD
),
CMD
(
SCAN_OFFLOAD_ABORT_CMD
),
CMD
(
SCAN_OFFLOAD_COMPLETE
),
...
...
@@ -303,6 +310,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD
(
REPLY_BEACON_FILTERING_CMD
),
CMD
(
REPLY_THERMAL_MNG_BACKOFF
),
CMD
(
MAC_PM_POWER_TABLE
),
CMD
(
BT_COEX_CI
),
};
#undef CMD
...
...
@@ -344,6 +352,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm
->
restart_fw
=
iwlwifi_mod_params
.
restart_fw
?
-
1
:
0
;
mvm
->
aux_queue
=
15
;
mvm
->
first_agg_queue
=
16
;
mvm
->
last_agg_queue
=
mvm
->
cfg
->
base_params
->
num_of_queues
-
1
;
if
(
mvm
->
cfg
->
base_params
->
num_of_queues
==
16
)
{
mvm
->
aux_queue
=
11
;
mvm
->
first_agg_queue
=
12
;
}
mutex_init
(
&
mvm
->
mutex
);
spin_lock_init
(
&
mvm
->
async_handlers_lock
);
INIT_LIST_HEAD
(
&
mvm
->
time_event_list
);
...
...
@@ -401,24 +417,32 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
IWL_INFO
(
mvm
,
"Detected %s, REV=0x%X
\n
"
,
mvm
->
cfg
->
name
,
mvm
->
trans
->
hw_rev
);
err
=
iwl_trans_start_hw
(
mvm
->
trans
);
if
(
err
)
goto
out_free
;
iwl_mvm_tt_initialize
(
mvm
);
mutex_lock
(
&
mvm
->
mutex
);
err
=
iwl_run_init_mvm_ucode
(
mvm
,
true
);
mutex_unlock
(
&
mvm
->
mutex
);
/* returns 0 if successful, 1 if success but in rfkill */
if
(
err
<
0
&&
!
iwlmvm_mod_params
.
init_dbg
)
{
IWL_ERR
(
mvm
,
"Failed to run INIT ucode: %d
\n
"
,
err
);
goto
out_free
;
}
/*
* If the NVM exists in an external file,
* there is no need to unnecessarily power up the NIC at driver load
*/
if
(
iwlwifi_mod_params
.
nvm_file
)
{
iwl_nvm_init
(
mvm
);
}
else
{
err
=
iwl_trans_start_hw
(
mvm
->
trans
);
if
(
err
)
goto
out_free
;
mutex_lock
(
&
mvm
->
mutex
);
err
=
iwl_run_init_mvm_ucode
(
mvm
,
true
);
mutex_unlock
(
&
mvm
->
mutex
);
/* returns 0 if successful, 1 if success but in rfkill */
if
(
err
<
0
&&
!
iwlmvm_mod_params
.
init_dbg
)
{
IWL_ERR
(
mvm
,
"Failed to run INIT ucode: %d
\n
"
,
err
);
goto
out_free
;
}
/* Stop the hw after the ALIVE and NVM has been read */
if
(
!
iwlmvm_mod_params
.
init_dbg
)
iwl_trans_stop_hw
(
mvm
->
trans
,
false
);
/* Stop the hw after the ALIVE and NVM has been read */
if
(
!
iwlmvm_mod_params
.
init_dbg
)
iwl_trans_stop_hw
(
mvm
->
trans
,
false
);
}
scan_size
=
sizeof
(
struct
iwl_scan_cmd
)
+
mvm
->
fw
->
ucode_capa
.
max_probe_length
+
...
...
@@ -449,7 +473,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
out_free:
iwl_phy_db_free
(
mvm
->
phy_db
);
kfree
(
mvm
->
scan_cmd
);
iwl_trans_stop_hw
(
trans
,
true
);
if
(
!
iwlwifi_mod_params
.
nvm_file
)
iwl_trans_stop_hw
(
trans
,
true
);
ieee80211_free_hw
(
mvm
->
hw
);
return
NULL
;
}
...
...
@@ -715,6 +740,9 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
case
IWL_MVM_SCAN_OS
:
ieee80211_scan_completed
(
mvm
->
hw
,
true
);
break
;
case
IWL_MVM_SCAN_SCHED
:
ieee80211_sched_scan_stopped
(
mvm
->
hw
);
break
;
}
if
(
mvm
->
restart_fw
>
0
)
...
...
drivers/net/wireless/iwlwifi/mvm/power.c
浏览文件 @
444474dd
...
...
@@ -297,11 +297,6 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
}
if
(
cmd
->
flags
&
cpu_to_le16
(
POWER_FLAGS_ADVANCE_PM_ENA_MSK
))
{
cmd
->
rx_data_timeout_uapsd
=
cpu_to_le32
(
IWL_MVM_UAPSD_RX_DATA_TIMEOUT
);
cmd
->
tx_data_timeout_uapsd
=
cpu_to_le32
(
IWL_MVM_UAPSD_TX_DATA_TIMEOUT
);
if
(
cmd
->
uapsd_ac_flags
==
(
BIT
(
IEEE80211_AC_VO
)
|
BIT
(
IEEE80211_AC_VI
)
|
BIT
(
IEEE80211_AC_BE
)
|
...
...
@@ -316,10 +311,31 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
}
cmd
->
uapsd_max_sp
=
IWL_UAPSD_MAX_SP
;
cmd
->
heavy_tx_thld_packets
=
IWL_MVM_PS_HEAVY_TX_THLD_PACKETS
;
cmd
->
heavy_rx_thld_packets
=
IWL_MVM_PS_HEAVY_RX_THLD_PACKETS
;
if
(
mvm
->
cur_ucode
==
IWL_UCODE_WOWLAN
||
cmd
->
flags
&
cpu_to_le16
(
POWER_FLAGS_SNOOZE_ENA_MSK
))
{
cmd
->
rx_data_timeout_uapsd
=
cpu_to_le32
(
IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT
);
cmd
->
tx_data_timeout_uapsd
=
cpu_to_le32
(
IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT
);
}
else
{
cmd
->
rx_data_timeout_uapsd
=
cpu_to_le32
(
IWL_MVM_UAPSD_RX_DATA_TIMEOUT
);
cmd
->
tx_data_timeout_uapsd
=
cpu_to_le32
(
IWL_MVM_UAPSD_TX_DATA_TIMEOUT
);
}
if
(
cmd
->
flags
&
cpu_to_le16
(
POWER_FLAGS_SNOOZE_ENA_MSK
))
{
cmd
->
heavy_tx_thld_packets
=
IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS
;
cmd
->
heavy_rx_thld_packets
=
IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS
;
}
else
{
cmd
->
heavy_tx_thld_packets
=
IWL_MVM_PS_HEAVY_TX_THLD_PACKETS
;
cmd
->
heavy_rx_thld_packets
=
IWL_MVM_PS_HEAVY_RX_THLD_PACKETS
;
}
cmd
->
heavy_tx_thld_percentage
=
IWL_MVM_PS_HEAVY_TX_THLD_PERCENT
;
cmd
->
heavy_rx_thld_percentage
=
...
...
@@ -427,6 +443,32 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
sizeof
(
cmd
),
&
cmd
);
}
static
int
iwl_mvm_power_update_device
(
struct
iwl_mvm
*
mvm
)
{
struct
iwl_device_power_cmd
cmd
=
{
.
flags
=
cpu_to_le16
(
DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK
),
};
if
(
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
))
return
0
;
if
(
iwlmvm_mod_params
.
power_scheme
==
IWL_POWER_SCHEME_CAM
)
cmd
.
flags
|=
cpu_to_le16
(
DEVICE_POWER_FLAGS_CAM_MSK
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
if
((
mvm
->
cur_ucode
==
IWL_UCODE_WOWLAN
)
?
mvm
->
disable_power_off_d3
:
mvm
->
disable_power_off
)
cmd
.
flags
&=
cpu_to_le16
(
~
DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK
);
#endif
IWL_DEBUG_POWER
(
mvm
,
"Sending device power command with flags = 0x%X
\n
"
,
cmd
.
flags
);
return
iwl_mvm_send_cmd_pdu
(
mvm
,
POWER_TABLE_CMD
,
CMD_SYNC
,
sizeof
(
cmd
),
&
cmd
);
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
static
int
iwl_mvm_power_mac_dbgfs_read
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
char
*
buf
,
...
...
@@ -437,10 +479,11 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
iwl_mvm_power_build_cmd
(
mvm
,
vif
,
&
cmd
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"disable_power_off = %d
\n
"
,
(
cmd
.
flags
&
cpu_to_le16
(
POWER_FLAGS_POWER_SAVE_ENA_MSK
))
?
0
:
1
);
if
(
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
))
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"disable_power_off = %d
\n
"
,
(
cmd
.
flags
&
cpu_to_le16
(
POWER_FLAGS_POWER_SAVE_ENA_MSK
))
?
0
:
1
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"power_scheme = %d
\n
"
,
iwlmvm_mod_params
.
power_scheme
);
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"flags = 0x%x
\n
"
,
...
...
@@ -606,6 +649,7 @@ int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm,
const
struct
iwl_mvm_power_ops
pm_mac_ops
=
{
.
power_update_mode
=
iwl_mvm_power_mac_update_mode
,
.
power_update_device_mode
=
iwl_mvm_power_update_device
,
.
power_disable
=
iwl_mvm_power_mac_disable
,
#ifdef CONFIG_IWLWIFI_DEBUGFS
.
power_dbgfs_read
=
iwl_mvm_power_mac_dbgfs_read
,
...
...
drivers/net/wireless/iwlwifi/mvm/quota.c
浏览文件 @
444474dd
...
...
@@ -110,7 +110,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
data
->
n_interfaces
[
id
]
++
;
break
;
case
NL80211_IFTYPE_AP
:
if
(
mvmvif
->
ap_active
)
case
NL80211_IFTYPE_ADHOC
:
if
(
mvmvif
->
ap_ibss_active
)
data
->
n_interfaces
[
id
]
++
;
break
;
case
NL80211_IFTYPE_MONITOR
:
...
...
@@ -119,16 +120,45 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
break
;
case
NL80211_IFTYPE_P2P_DEVICE
:
break
;
case
NL80211_IFTYPE_ADHOC
:
if
(
vif
->
bss_conf
.
ibss_joined
)
data
->
n_interfaces
[
id
]
++
;
break
;
default:
WARN_ON_ONCE
(
1
);
break
;
}
}
static
void
iwl_mvm_adjust_quota_for_noa
(
struct
iwl_mvm
*
mvm
,
struct
iwl_time_quota_cmd
*
cmd
)
{
#ifdef CONFIG_NL80211_TESTMODE
struct
iwl_mvm_vif
*
mvmvif
;
int
i
,
phy_id
=
-
1
,
beacon_int
=
0
;
if
(
!
mvm
->
noa_duration
||
!
mvm
->
noa_vif
)
return
;
mvmvif
=
iwl_mvm_vif_from_mac80211
(
mvm
->
noa_vif
);
if
(
!
mvmvif
->
ap_ibss_active
)
return
;
phy_id
=
mvmvif
->
phy_ctxt
->
id
;
beacon_int
=
mvm
->
noa_vif
->
bss_conf
.
beacon_int
;
for
(
i
=
0
;
i
<
MAX_BINDINGS
;
i
++
)
{
u32
id_n_c
=
le32_to_cpu
(
cmd
->
quotas
[
i
].
id_and_color
);
u32
id
=
(
id_n_c
&
FW_CTXT_ID_MSK
)
>>
FW_CTXT_ID_POS
;
u32
quota
=
le32_to_cpu
(
cmd
->
quotas
[
i
].
quota
);
if
(
id
!=
phy_id
)
continue
;
quota
*=
(
beacon_int
-
mvm
->
noa_duration
);
quota
/=
beacon_int
;
cmd
->
quotas
[
i
].
quota
=
cpu_to_le32
(
quota
);
}
#endif
}
int
iwl_mvm_update_quotas
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
newvif
)
{
struct
iwl_time_quota_cmd
cmd
=
{};
...
...
@@ -196,6 +226,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
/* Give the remainder of the session to the first binding */
le32_add_cpu
(
&
cmd
.
quotas
[
0
].
quota
,
quota_rem
);
iwl_mvm_adjust_quota_for_noa
(
mvm
,
&
cmd
);
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
TIME_QUOTA_CMD
,
CMD_SYNC
,
sizeof
(
cmd
),
&
cmd
);
if
(
ret
)
...
...
drivers/net/wireless/iwlwifi/mvm/rs.c
浏览文件 @
444474dd
此差异已折叠。
点击以展开。
drivers/net/wireless/iwlwifi/mvm/rs.h
浏览文件 @
444474dd
...
...
@@ -35,9 +35,11 @@
#include "iwl-trans.h"
struct
iwl_rs_rate_info
{
u8
plcp
;
/* uCode API: IWL_RATE_6M_PLCP, etc. */
u8
plcp_siso
;
/* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
u8
plcp_mimo2
;
/* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
u8
plcp
;
/* uCode API: IWL_RATE_6M_PLCP, etc. */
u8
plcp_ht_siso
;
/* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
u8
plcp_ht_mimo2
;
/* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
u8
plcp_vht_siso
;
u8
plcp_vht_mimo2
;
u8
prev_rs
;
/* previous rate used in rs algo */
u8
next_rs
;
/* next rate used in rs algo */
};
...
...
@@ -83,35 +85,52 @@ enum {
#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
/* uCode API values for
OFDM high-throughput (HT)
bit rates */
/* uCode API values for
HT/VHT
bit rates */
enum
{
IWL_RATE_SISO_6M_PLCP
=
0
,
IWL_RATE_SISO_12M_PLCP
=
1
,
IWL_RATE_SISO_18M_PLCP
=
2
,
IWL_RATE_SISO_24M_PLCP
=
3
,
IWL_RATE_SISO_36M_PLCP
=
4
,
IWL_RATE_SISO_48M_PLCP
=
5
,
IWL_RATE_SISO_54M_PLCP
=
6
,
IWL_RATE_SISO_60M_PLCP
=
7
,
IWL_RATE_MIMO2_6M_PLCP
=
0x8
,
IWL_RATE_MIMO2_12M_PLCP
=
0x9
,
IWL_RATE_MIMO2_18M_PLCP
=
0xa
,
IWL_RATE_MIMO2_24M_PLCP
=
0xb
,
IWL_RATE_MIMO2_36M_PLCP
=
0xc
,
IWL_RATE_MIMO2_48M_PLCP
=
0xd
,
IWL_RATE_MIMO2_54M_PLCP
=
0xe
,
IWL_RATE_MIMO2_60M_PLCP
=
0xf
,
IWL_RATE_MIMO3_6M_PLCP
=
0x10
,
IWL_RATE_MIMO3_12M_PLCP
=
0x11
,
IWL_RATE_MIMO3_18M_PLCP
=
0x12
,
IWL_RATE_MIMO3_24M_PLCP
=
0x13
,
IWL_RATE_MIMO3_36M_PLCP
=
0x14
,
IWL_RATE_MIMO3_48M_PLCP
=
0x15
,
IWL_RATE_MIMO3_54M_PLCP
=
0x16
,
IWL_RATE_MIMO3_60M_PLCP
=
0x17
,
IWL_RATE_SISO_INVM_PLCP
,
IWL_RATE_MIMO2_INVM_PLCP
=
IWL_RATE_SISO_INVM_PLCP
,
IWL_RATE_MIMO3_INVM_PLCP
=
IWL_RATE_SISO_INVM_PLCP
,
IWL_RATE_HT_SISO_MCS_0_PLCP
=
0
,
IWL_RATE_HT_SISO_MCS_1_PLCP
=
1
,
IWL_RATE_HT_SISO_MCS_2_PLCP
=
2
,
IWL_RATE_HT_SISO_MCS_3_PLCP
=
3
,
IWL_RATE_HT_SISO_MCS_4_PLCP
=
4
,
IWL_RATE_HT_SISO_MCS_5_PLCP
=
5
,
IWL_RATE_HT_SISO_MCS_6_PLCP
=
6
,
IWL_RATE_HT_SISO_MCS_7_PLCP
=
7
,
IWL_RATE_HT_MIMO2_MCS_0_PLCP
=
0x8
,
IWL_RATE_HT_MIMO2_MCS_1_PLCP
=
0x9
,
IWL_RATE_HT_MIMO2_MCS_2_PLCP
=
0xA
,
IWL_RATE_HT_MIMO2_MCS_3_PLCP
=
0xB
,
IWL_RATE_HT_MIMO2_MCS_4_PLCP
=
0xC
,
IWL_RATE_HT_MIMO2_MCS_5_PLCP
=
0xD
,
IWL_RATE_HT_MIMO2_MCS_6_PLCP
=
0xE
,
IWL_RATE_HT_MIMO2_MCS_7_PLCP
=
0xF
,
IWL_RATE_VHT_SISO_MCS_0_PLCP
=
0
,
IWL_RATE_VHT_SISO_MCS_1_PLCP
=
1
,
IWL_RATE_VHT_SISO_MCS_2_PLCP
=
2
,
IWL_RATE_VHT_SISO_MCS_3_PLCP
=
3
,
IWL_RATE_VHT_SISO_MCS_4_PLCP
=
4
,
IWL_RATE_VHT_SISO_MCS_5_PLCP
=
5
,
IWL_RATE_VHT_SISO_MCS_6_PLCP
=
6
,
IWL_RATE_VHT_SISO_MCS_7_PLCP
=
7
,
IWL_RATE_VHT_SISO_MCS_8_PLCP
=
8
,
IWL_RATE_VHT_SISO_MCS_9_PLCP
=
9
,
IWL_RATE_VHT_MIMO2_MCS_0_PLCP
=
0x10
,
IWL_RATE_VHT_MIMO2_MCS_1_PLCP
=
0x11
,
IWL_RATE_VHT_MIMO2_MCS_2_PLCP
=
0x12
,
IWL_RATE_VHT_MIMO2_MCS_3_PLCP
=
0x13
,
IWL_RATE_VHT_MIMO2_MCS_4_PLCP
=
0x14
,
IWL_RATE_VHT_MIMO2_MCS_5_PLCP
=
0x15
,
IWL_RATE_VHT_MIMO2_MCS_6_PLCP
=
0x16
,
IWL_RATE_VHT_MIMO2_MCS_7_PLCP
=
0x17
,
IWL_RATE_VHT_MIMO2_MCS_8_PLCP
=
0x18
,
IWL_RATE_VHT_MIMO2_MCS_9_PLCP
=
0x19
,
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
IWL_RATE_HT_MIMO2_MCS_INV_PLCP
=
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
IWL_RATE_VHT_SISO_MCS_INV_PLCP
=
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
IWL_RATE_VHT_MIMO2_MCS_INV_PLCP
=
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
IWL_RATE_HT_SISO_MCS_8_PLCP
=
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
IWL_RATE_HT_SISO_MCS_9_PLCP
=
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
IWL_RATE_HT_MIMO2_MCS_8_PLCP
=
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
IWL_RATE_HT_MIMO2_MCS_9_PLCP
=
IWL_RATE_HT_SISO_MCS_INV_PLCP
,
};
#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
...
...
@@ -139,25 +158,33 @@ enum {
#define IWL_RATE_DECREASE_TH 1920
/* 15% */
/* possible actions when in legacy mode */
#define IWL_LEGACY_SWITCH_ANTENNA1 0
#define IWL_LEGACY_SWITCH_ANTENNA2 1
#define IWL_LEGACY_SWITCH_SISO 2
#define IWL_LEGACY_SWITCH_MIMO2 3
enum
{
IWL_LEGACY_SWITCH_ANTENNA
,
IWL_LEGACY_SWITCH_SISO
,
IWL_LEGACY_SWITCH_MIMO2
,
IWL_LEGACY_FIRST_ACTION
=
IWL_LEGACY_SWITCH_ANTENNA
,
IWL_LEGACY_LAST_ACTION
=
IWL_LEGACY_SWITCH_MIMO2
,
};
/* possible actions when in siso mode */
#define IWL_SISO_SWITCH_ANTENNA1 0
#define IWL_SISO_SWITCH_ANTENNA2 1
#define IWL_SISO_SWITCH_MIMO2 2
#define IWL_SISO_SWITCH_GI 3
enum
{
IWL_SISO_SWITCH_ANTENNA
,
IWL_SISO_SWITCH_MIMO2
,
IWL_SISO_SWITCH_GI
,
IWL_SISO_FIRST_ACTION
=
IWL_SISO_SWITCH_ANTENNA
,
IWL_SISO_LAST_ACTION
=
IWL_SISO_SWITCH_GI
,
};
/* possible actions when in mimo mode */
#define IWL_MIMO2_SWITCH_ANTENNA1 0
#define IWL_MIMO2_SWITCH_ANTENNA2 1
#define IWL_MIMO2_SWITCH_SISO_A 2
#define IWL_MIMO2_SWITCH_SISO_B 3
#define IWL_MIMO2_SWITCH_GI 4
enum
{
IWL_MIMO2_SWITCH_SISO_A
,
IWL_MIMO2_SWITCH_SISO_B
,
IWL_MIMO2_SWITCH_GI
,
IWL_MIMO2_FIRST_ACTION
=
IWL_MIMO2_SWITCH_SISO_A
,
IWL_MIMO2_LAST_ACTION
=
IWL_MIMO2_SWITCH_GI
,
};
#define IWL_MAX_SEARCH IWL_MIMO2_
SWITCH_GI
#define IWL_MAX_SEARCH IWL_MIMO2_
LAST_ACTION
#define IWL_ACTION_LIMIT 3
/* # possible actions */
...
...
@@ -188,20 +215,31 @@ enum {
enum
iwl_table_type
{
LQ_NONE
,
LQ_G
,
/* legacy types */
LQ_A
,
LQ_SISO
,
/* high-throughput types */
LQ_MIMO2
,
LQ_LEGACY_G
,
/* legacy types */
LQ_LEGACY_A
,
LQ_HT_SISO
,
/* HT types */
LQ_HT_MIMO2
,
LQ_VHT_SISO
,
/* VHT types */
LQ_VHT_MIMO2
,
LQ_MAX
,
};
#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
#define is_siso(tbl) ((tbl) == LQ_SISO)
#define is_mimo2(tbl) ((tbl) == LQ_MIMO2)
#define is_mimo(tbl) is_mimo2(tbl)
#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
#define is_a_band(tbl) ((tbl) == LQ_A)
#define is_g_and(tbl) ((tbl) == LQ_G)
#define is_legacy(tbl) (((tbl) == LQ_LEGACY_G) || ((tbl) == LQ_LEGACY_A))
#define is_ht_siso(tbl) ((tbl) == LQ_HT_SISO)
#define is_ht_mimo2(tbl) ((tbl) == LQ_HT_MIMO2)
#define is_vht_siso(tbl) ((tbl) == LQ_VHT_SISO)
#define is_vht_mimo2(tbl) ((tbl) == LQ_VHT_MIMO2)
#define is_siso(tbl) (is_ht_siso(tbl) || is_vht_siso(tbl))
#define is_mimo2(tbl) (is_ht_mimo2(tbl) || is_vht_mimo2(tbl))
#define is_mimo(tbl) (is_mimo2(tbl))
#define is_ht(tbl) (is_ht_siso(tbl) || is_ht_mimo2(tbl))
#define is_vht(tbl) (is_vht_siso(tbl) || is_vht_mimo2(tbl))
#define is_a_band(tbl) ((tbl) == LQ_LEGACY_A)
#define is_g_band(tbl) ((tbl) == LQ_LEGACY_G)
#define is_ht20(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_20)
#define is_ht40(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_40)
#define is_ht80(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_80)
#define IWL_MAX_MCS_DISPLAY_SIZE 12
...
...
@@ -232,7 +270,7 @@ struct iwl_scale_tbl_info {
enum
iwl_table_type
lq_type
;
u8
ant_type
;
u8
is_SGI
;
/* 1 = short guard interval */
u
8
is_ht40
;
/* 1 = 40 MHz channel width
*/
u
32
bw
;
/* channel bandwidth; RATE_MCS_CHAN_WIDTH_XX
*/
u8
action
;
/* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
u8
max_search
;
/* maximun number of tables we can search */
s32
*
expected_tpt
;
/* throughput metrics; expected_tpt_G, etc. */
...
...
@@ -262,7 +300,7 @@ struct iwl_lq_sta {
u64
flush_timer
;
/* time staying in mode before new search */
u8
action_counter
;
/* # mode-switch actions tried */
u8
is_green
;
bool
is_vht
;
enum
ieee80211_band
band
;
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
...
...
drivers/net/wireless/iwlwifi/mvm/rx.c
浏览文件 @
444474dd
...
...
@@ -422,6 +422,27 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
mvmvif
->
bf_data
.
ave_beacon_signal
=
sig
;
/* BT Coex */
if
(
mvmvif
->
bf_data
.
bt_coex_min_thold
!=
mvmvif
->
bf_data
.
bt_coex_max_thold
)
{
last_event
=
mvmvif
->
bf_data
.
last_bt_coex_event
;
if
(
sig
>
mvmvif
->
bf_data
.
bt_coex_max_thold
&&
(
last_event
<=
mvmvif
->
bf_data
.
bt_coex_min_thold
||
last_event
==
0
))
{
mvmvif
->
bf_data
.
last_bt_coex_event
=
sig
;
IWL_DEBUG_RX
(
mvm
,
"cqm_iterator bt coex high %d
\n
"
,
sig
);
iwl_mvm_bt_rssi_event
(
mvm
,
vif
,
RSSI_EVENT_HIGH
);
}
else
if
(
sig
<
mvmvif
->
bf_data
.
bt_coex_min_thold
&&
(
last_event
>=
mvmvif
->
bf_data
.
bt_coex_max_thold
||
last_event
==
0
))
{
mvmvif
->
bf_data
.
last_bt_coex_event
=
sig
;
IWL_DEBUG_RX
(
mvm
,
"cqm_iterator bt coex low %d
\n
"
,
sig
);
iwl_mvm_bt_rssi_event
(
mvm
,
vif
,
RSSI_EVENT_LOW
);
}
}
if
(
!
(
vif
->
driver_flags
&
IEEE80211_VIF_SUPPORTS_CQM_RSSI
))
return
;
...
...
drivers/net/wireless/iwlwifi/mvm/scan.c
浏览文件 @
444474dd
...
...
@@ -74,8 +74,12 @@
static
inline
__le16
iwl_mvm_scan_rx_chain
(
struct
iwl_mvm
*
mvm
)
{
u16
rx_chain
;
u8
rx_ant
=
iwl_fw_valid_rx_ant
(
mvm
->
fw
)
;
u8
rx_ant
;
if
(
mvm
->
scan_rx_ant
!=
ANT_NONE
)
rx_ant
=
mvm
->
scan_rx_ant
;
else
rx_ant
=
iwl_fw_valid_rx_ant
(
mvm
->
fw
);
rx_chain
=
rx_ant
<<
PHY_RX_CHAIN_VALID_POS
;
rx_chain
|=
rx_ant
<<
PHY_RX_CHAIN_FORCE_MIMO_SEL_POS
;
rx_chain
|=
rx_ant
<<
PHY_RX_CHAIN_FORCE_SEL_POS
;
...
...
@@ -133,11 +137,12 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
* request.
*/
static
void
iwl_mvm_scan_fill_ssids
(
struct
iwl_scan_cmd
*
cmd
,
struct
cfg80211_scan_request
*
req
)
struct
cfg80211_scan_request
*
req
,
int
first
)
{
int
fw_idx
,
req_idx
;
for
(
req_idx
=
req
->
n_ssids
-
1
,
fw_idx
=
0
;
req_idx
>
0
;
for
(
req_idx
=
req
->
n_ssids
-
1
,
fw_idx
=
0
;
req_idx
>
=
first
;
req_idx
--
,
fw_idx
++
)
{
cmd
->
direct_scan
[
fw_idx
].
id
=
WLAN_EID_SSID
;
cmd
->
direct_scan
[
fw_idx
].
len
=
req
->
ssids
[
req_idx
].
ssid_len
;
...
...
@@ -153,9 +158,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd,
* just to notify that this scan is active and not passive.
* In order to notify the FW of the number of SSIDs we wish to scan (including
* the zero-length one), we need to set the corresponding bits in chan->type,
* one for each SSID, and set the active bit (first).
The first SSID is already
*
included in the probe template, so we need to set only req->n_ssids - 1 bits
* in addition to the first bit.
* one for each SSID, and set the active bit (first).
If the first SSID is
*
already included in the probe template, so we need to set only
*
req->n_ssids - 1 bits
in addition to the first bit.
*/
static
u16
iwl_mvm_get_active_dwell
(
enum
ieee80211_band
band
,
int
n_ssids
)
{
...
...
@@ -170,7 +175,8 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
}
static
void
iwl_mvm_scan_fill_channels
(
struct
iwl_scan_cmd
*
cmd
,
struct
cfg80211_scan_request
*
req
)
struct
cfg80211_scan_request
*
req
,
bool
basic_ssid
)
{
u16
passive_dwell
=
iwl_mvm_get_passive_dwell
(
req
->
channels
[
0
]
->
band
);
u16
active_dwell
=
iwl_mvm_get_active_dwell
(
req
->
channels
[
0
]
->
band
,
...
...
@@ -178,10 +184,14 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
struct
iwl_scan_channel
*
chan
=
(
struct
iwl_scan_channel
*
)
(
cmd
->
data
+
le16_to_cpu
(
cmd
->
tx_cmd
.
len
));
int
i
;
int
type
=
BIT
(
req
->
n_ssids
)
-
1
;
if
(
!
basic_ssid
)
type
|=
BIT
(
req
->
n_ssids
);
for
(
i
=
0
;
i
<
cmd
->
channel_count
;
i
++
)
{
chan
->
channel
=
cpu_to_le16
(
req
->
channels
[
i
]
->
hw_value
);
chan
->
type
=
cpu_to_le32
(
BIT
(
req
->
n_ssids
)
-
1
);
chan
->
type
=
cpu_to_le32
(
type
);
if
(
req
->
channels
[
i
]
->
flags
&
IEEE80211_CHAN_PASSIVE_SCAN
)
chan
->
type
&=
cpu_to_le32
(
~
SCAN_CHANNEL_TYPE_ACTIVE
);
chan
->
active_dwell
=
cpu_to_le16
(
active_dwell
);
...
...
@@ -268,6 +278,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
u32
status
;
int
ssid_len
=
0
;
u8
*
ssid
=
NULL
;
bool
basic_ssid
=
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID
);
lockdep_assert_held
(
&
mvm
->
mutex
);
BUG_ON
(
mvm
->
scan_cmd
==
NULL
);
...
...
@@ -302,14 +314,16 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
if
(
req
->
n_ssids
>
0
)
{
cmd
->
passive2active
=
cpu_to_le16
(
1
);
cmd
->
scan_flags
|=
SCAN_FLAGS_PASSIVE2ACTIVE
;
ssid
=
req
->
ssids
[
0
].
ssid
;
ssid_len
=
req
->
ssids
[
0
].
ssid_len
;
if
(
basic_ssid
)
{
ssid
=
req
->
ssids
[
0
].
ssid
;
ssid_len
=
req
->
ssids
[
0
].
ssid_len
;
}
}
else
{
cmd
->
passive2active
=
0
;
cmd
->
scan_flags
&=
~
SCAN_FLAGS_PASSIVE2ACTIVE
;
}
iwl_mvm_scan_fill_ssids
(
cmd
,
req
);
iwl_mvm_scan_fill_ssids
(
cmd
,
req
,
basic_ssid
?
1
:
0
);
cmd
->
tx_cmd
.
tx_flags
=
cpu_to_le32
(
TX_CMD_FLG_SEQ_CTL
);
cmd
->
tx_cmd
.
sta_id
=
mvm
->
aux_sta
.
sta_id
;
...
...
@@ -326,7 +340,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
req
->
ie
,
req
->
ie_len
,
mvm
->
fw
->
ucode_capa
.
max_probe_length
));
iwl_mvm_scan_fill_channels
(
cmd
,
req
);
iwl_mvm_scan_fill_channels
(
cmd
,
req
,
basic_ssid
);
cmd
->
len
=
cpu_to_le16
(
sizeof
(
struct
iwl_scan_cmd
)
+
le16_to_cpu
(
cmd
->
tx_cmd
.
len
)
+
...
...
@@ -377,6 +391,21 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
return
0
;
}
int
iwl_mvm_rx_sched_scan_results
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
)
{
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_sched_scan_results
*
notif
=
(
void
*
)
pkt
->
data
;
if
(
notif
->
client_bitmap
&
SCAN_CLIENT_SCHED_SCAN
)
{
IWL_DEBUG_SCAN
(
mvm
,
"Scheduled scan results
\n
"
);
ieee80211_sched_scan_results
(
mvm
->
hw
);
}
return
0
;
}
static
bool
iwl_mvm_scan_abort_notif
(
struct
iwl_notif_wait_data
*
notif_wait
,
struct
iwl_rx_packet
*
pkt
,
void
*
data
)
{
...
...
@@ -437,3 +466,406 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
out_remove_notif:
iwl_remove_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_abort
);
}
int
iwl_mvm_rx_scan_offload_complete_notif
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
)
{
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_scan_offload_complete
*
scan_notif
=
(
void
*
)
pkt
->
data
;
IWL_DEBUG_SCAN
(
mvm
,
"Scheduled scan completed, status %s
\n
"
,
scan_notif
->
status
==
IWL_SCAN_OFFLOAD_COMPLETED
?
"completed"
:
"aborted"
);
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
ieee80211_sched_scan_stopped
(
mvm
->
hw
);
return
0
;
}
static
void
iwl_scan_offload_build_tx_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sched_scan_ies
*
ies
,
enum
ieee80211_band
band
,
struct
iwl_tx_cmd
*
cmd
,
u8
*
data
)
{
u16
cmd_len
;
cmd
->
tx_flags
=
cpu_to_le32
(
TX_CMD_FLG_SEQ_CTL
);
cmd
->
life_time
=
cpu_to_le32
(
TX_CMD_LIFE_TIME_INFINITE
);
cmd
->
sta_id
=
mvm
->
aux_sta
.
sta_id
;
cmd
->
rate_n_flags
=
iwl_mvm_scan_rate_n_flags
(
mvm
,
band
,
false
);
cmd_len
=
iwl_mvm_fill_probe_req
((
struct
ieee80211_mgmt
*
)
data
,
vif
->
addr
,
1
,
NULL
,
0
,
ies
->
ie
[
band
],
ies
->
len
[
band
],
SCAN_OFFLOAD_PROBE_REQ_SIZE
);
cmd
->
len
=
cpu_to_le16
(
cmd_len
);
}
static
void
iwl_build_scan_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_sched_scan_request
*
req
,
struct
iwl_scan_offload_cmd
*
scan
)
{
scan
->
channel_count
=
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_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
scan
->
good_CRC_th
=
IWL_GOOD_CRC_TH_DEFAULT
;
scan
->
rx_chain
=
iwl_mvm_scan_rx_chain
(
mvm
);
scan
->
max_out_time
=
cpu_to_le32
(
200
*
1024
);
scan
->
suspend_time
=
iwl_mvm_scan_suspend_time
(
vif
);
scan
->
filter_flags
|=
cpu_to_le32
(
MAC_FILTER_ACCEPT_GRP
|
MAC_FILTER_IN_BEACON
);
scan
->
scan_type
=
cpu_to_le32
(
SCAN_TYPE_BACKGROUND
);
scan
->
rep_count
=
cpu_to_le32
(
1
);
}
static
int
iwl_ssid_exist
(
u8
*
ssid
,
u8
ssid_len
,
struct
iwl_ssid_ie
*
ssid_list
)
{
int
i
;
for
(
i
=
0
;
i
<
PROBE_OPTION_MAX
;
i
++
)
{
if
(
!
ssid_list
[
i
].
len
)
break
;
if
(
ssid_list
[
i
].
len
==
ssid_len
&&
!
memcmp
(
ssid_list
->
ssid
,
ssid
,
ssid_len
))
return
i
;
}
return
-
1
;
}
static
void
iwl_scan_offload_build_ssid
(
struct
cfg80211_sched_scan_request
*
req
,
struct
iwl_scan_offload_cmd
*
scan
,
u32
*
ssid_bitmap
)
{
int
i
,
j
;
int
index
;
/*
* copy SSIDs from match list.
* iwl_config_sched_scan_profiles() uses the order of these ssids to
* config match list.
*/
for
(
i
=
0
;
i
<
req
->
n_match_sets
&&
i
<
PROBE_OPTION_MAX
;
i
++
)
{
scan
->
direct_scan
[
i
].
id
=
WLAN_EID_SSID
;
scan
->
direct_scan
[
i
].
len
=
req
->
match_sets
[
i
].
ssid
.
ssid_len
;
memcpy
(
scan
->
direct_scan
[
i
].
ssid
,
req
->
match_sets
[
i
].
ssid
.
ssid
,
scan
->
direct_scan
[
i
].
len
);
}
/* add SSIDs from scan SSID list */
*
ssid_bitmap
=
0
;
for
(
j
=
0
;
j
<
req
->
n_ssids
&&
i
<
PROBE_OPTION_MAX
;
j
++
)
{
index
=
iwl_ssid_exist
(
req
->
ssids
[
j
].
ssid
,
req
->
ssids
[
j
].
ssid_len
,
scan
->
direct_scan
);
if
(
index
<
0
)
{
if
(
!
req
->
ssids
[
j
].
ssid_len
)
continue
;
scan
->
direct_scan
[
i
].
id
=
WLAN_EID_SSID
;
scan
->
direct_scan
[
i
].
len
=
req
->
ssids
[
j
].
ssid_len
;
memcpy
(
scan
->
direct_scan
[
i
].
ssid
,
req
->
ssids
[
j
].
ssid
,
scan
->
direct_scan
[
i
].
len
);
*
ssid_bitmap
|=
BIT
(
i
+
1
);
i
++
;
}
else
{
*
ssid_bitmap
|=
BIT
(
index
+
1
);
}
}
}
static
void
iwl_build_channel_cfg
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
,
struct
iwl_scan_channel_cfg
*
channels
,
enum
ieee80211_band
band
,
int
*
head
,
int
*
tail
,
u32
ssid_bitmap
)
{
struct
ieee80211_supported_band
*
s_band
;
int
n_probes
=
req
->
n_ssids
;
int
n_channels
=
req
->
n_channels
;
u8
active_dwell
,
passive_dwell
;
int
i
,
j
,
index
=
0
;
bool
partial
;
/*
* We have to configure all supported channels, even if we don't want to
* scan on them, but we have to send channels in the order that we want
* to scan. So add requested channels to head of the list and others to
* the end.
*/
active_dwell
=
iwl_mvm_get_active_dwell
(
band
,
n_probes
);
passive_dwell
=
iwl_mvm_get_passive_dwell
(
band
);
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
]
=
active_dwell
;
channels
->
dwell_time
[
index
][
1
]
=
passive_dwell
;
channels
->
iter_count
[
index
]
=
cpu_to_le16
(
1
);
channels
->
iter_interval
[
index
]
=
0
;
if
(
!
(
s_band
->
channels
[
i
].
flags
&
IEEE80211_CHAN_PASSIVE_SCAN
))
channels
->
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
);
if
(
s_band
->
channels
[
i
].
flags
&
IEEE80211_CHAN_NO_HT40
)
channels
->
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
);
}
}
int
iwl_mvm_config_sched_scan
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_sched_scan_request
*
req
,
struct
ieee80211_sched_scan_ies
*
ies
)
{
int
supported_bands
=
0
;
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
;
u32
ssid_bitmap
;
int
cmd_len
;
int
ret
;
struct
iwl_scan_offload_cfg
*
scan_cfg
;
struct
iwl_host_cmd
cmd
=
{
.
id
=
SCAN_OFFLOAD_CONFIG_CMD
,
.
flags
=
CMD_SYNC
,
};
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
band_2ghz
)
supported_bands
++
;
if
(
band_5ghz
)
supported_bands
++
;
cmd_len
=
sizeof
(
struct
iwl_scan_offload_cfg
)
+
supported_bands
*
SCAN_OFFLOAD_PROBE_REQ_SIZE
;
scan_cfg
=
kzalloc
(
cmd_len
,
GFP_KERNEL
);
if
(
!
scan_cfg
)
return
-
ENOMEM
;
iwl_build_scan_cmd
(
mvm
,
vif
,
req
,
&
scan_cfg
->
scan_cmd
);
scan_cfg
->
scan_cmd
.
len
=
cpu_to_le16
(
cmd_len
);
iwl_scan_offload_build_ssid
(
req
,
&
scan_cfg
->
scan_cmd
,
&
ssid_bitmap
);
/* build tx frames for supported bands */
if
(
band_2ghz
)
{
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
,
ssid_bitmap
);
}
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
+
SCAN_OFFLOAD_PROBE_REQ_SIZE
);
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
IEEE80211_BAND_5GHZ
,
&
head
,
&
tail
,
ssid_bitmap
);
}
cmd
.
data
[
0
]
=
scan_cfg
;
cmd
.
len
[
0
]
=
cmd_len
;
cmd
.
dataflags
[
0
]
=
IWL_HCMD_DFL_NOCOPY
;
IWL_DEBUG_SCAN
(
mvm
,
"Sending scheduled scan config
\n
"
);
ret
=
iwl_mvm_send_cmd
(
mvm
,
&
cmd
);
kfree
(
scan_cfg
);
return
ret
;
}
int
iwl_mvm_config_sched_scan_profiles
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
)
{
struct
iwl_scan_offload_profile
*
profile
;
struct
iwl_scan_offload_profile_cfg
*
profile_cfg
;
struct
iwl_scan_offload_blacklist
*
blacklist
;
struct
iwl_host_cmd
cmd
=
{
.
id
=
SCAN_OFFLOAD_UPDATE_PROFILES_CMD
,
.
flags
=
CMD_SYNC
,
.
len
[
1
]
=
sizeof
(
*
profile_cfg
),
.
dataflags
[
0
]
=
IWL_HCMD_DFL_NOCOPY
,
.
dataflags
[
1
]
=
IWL_HCMD_DFL_NOCOPY
,
};
int
blacklist_len
;
int
i
;
int
ret
;
if
(
WARN_ON
(
req
->
n_match_sets
>
IWL_SCAN_MAX_PROFILES
))
return
-
EIO
;
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_SHORT_BL
)
blacklist_len
=
IWL_SCAN_SHORT_BLACKLIST_LEN
;
else
blacklist_len
=
IWL_SCAN_MAX_BLACKLIST_LEN
;
blacklist
=
kzalloc
(
sizeof
(
*
blacklist
)
*
blacklist_len
,
GFP_KERNEL
);
if
(
!
blacklist
)
return
-
ENOMEM
;
profile_cfg
=
kzalloc
(
sizeof
(
*
profile_cfg
),
GFP_KERNEL
);
if
(
!
profile_cfg
)
{
ret
=
-
ENOMEM
;
goto
free_blacklist
;
}
cmd
.
data
[
0
]
=
blacklist
;
cmd
.
len
[
0
]
=
sizeof
(
*
blacklist
)
*
blacklist_len
;
cmd
.
data
[
1
]
=
profile_cfg
;
/* No blacklist configuration */
profile_cfg
->
num_profiles
=
req
->
n_match_sets
;
profile_cfg
->
active_clients
=
SCAN_CLIENT_SCHED_SCAN
;
profile_cfg
->
pass_match
=
SCAN_CLIENT_SCHED_SCAN
;
profile_cfg
->
match_notify
=
SCAN_CLIENT_SCHED_SCAN
;
for
(
i
=
0
;
i
<
req
->
n_match_sets
;
i
++
)
{
profile
=
&
profile_cfg
->
profiles
[
i
];
profile
->
ssid_index
=
i
;
/* Support any cipher and auth algorithm */
profile
->
unicast_cipher
=
0xff
;
profile
->
auth_alg
=
0xff
;
profile
->
network_type
=
IWL_NETWORK_TYPE_ANY
;
profile
->
band_selection
=
IWL_SCAN_OFFLOAD_SELECT_ANY
;
profile
->
client_bitmap
=
SCAN_CLIENT_SCHED_SCAN
;
}
IWL_DEBUG_SCAN
(
mvm
,
"Sending scheduled scan profile config
\n
"
);
ret
=
iwl_mvm_send_cmd
(
mvm
,
&
cmd
);
kfree
(
profile_cfg
);
free_blacklist:
kfree
(
blacklist
);
return
ret
;
}
int
iwl_mvm_sched_scan_start
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
)
{
struct
iwl_scan_offload_req
scan_req
=
{
.
watchdog
=
IWL_SCHED_SCAN_WATCHDOG
,
.
schedule_line
[
0
].
iterations
=
IWL_FAST_SCHED_SCAN_ITERATIONS
,
.
schedule_line
[
0
].
delay
=
req
->
interval
/
1000
,
.
schedule_line
[
0
].
full_scan_mul
=
1
,
.
schedule_line
[
1
].
iterations
=
0xff
,
.
schedule_line
[
1
].
delay
=
req
->
interval
/
1000
,
.
schedule_line
[
1
].
full_scan_mul
=
IWL_FULL_SCAN_MULTIPLIER
,
};
if
(
req
->
n_match_sets
&&
req
->
match_sets
[
0
].
ssid
.
ssid_len
)
{
IWL_DEBUG_SCAN
(
mvm
,
"Sending scheduled scan with filtering, filter len %d
\n
"
,
req
->
n_match_sets
);
scan_req
.
flags
|=
cpu_to_le16
(
IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID
);
}
else
{
IWL_DEBUG_SCAN
(
mvm
,
"Sending Scheduled scan without filtering
\n
"
);
}
return
iwl_mvm_send_cmd_pdu
(
mvm
,
SCAN_OFFLOAD_REQUEST_CMD
,
CMD_SYNC
,
sizeof
(
scan_req
),
&
scan_req
);
}
static
int
iwl_mvm_send_sched_scan_abort
(
struct
iwl_mvm
*
mvm
)
{
int
ret
;
struct
iwl_host_cmd
cmd
=
{
.
id
=
SCAN_OFFLOAD_ABORT_CMD
,
.
flags
=
CMD_SYNC
,
};
u32
status
;
/* Exit instantly with error when device is not ready
* to receive scan abort command or it does not perform
* scheduled scan currently */
if
(
mvm
->
scan_status
!=
IWL_MVM_SCAN_SCHED
)
return
-
EIO
;
ret
=
iwl_mvm_send_cmd_status
(
mvm
,
&
cmd
,
&
status
);
if
(
ret
)
return
ret
;
if
(
status
!=
CAN_ABORT_STATUS
)
{
/*
* The scan abort will return 1 for success or
* 2 for "failure". A failure condition can be
* due to simply not being in an active scan which
* can occur if we send the scan abort before the
* microcode has notified us that a scan is completed.
*/
IWL_DEBUG_SCAN
(
mvm
,
"SCAN OFFLOAD ABORT ret %d.
\n
"
,
status
);
ret
=
-
EIO
;
}
return
ret
;
}
void
iwl_mvm_sched_scan_stop
(
struct
iwl_mvm
*
mvm
)
{
int
ret
;
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
mvm
->
scan_status
!=
IWL_MVM_SCAN_SCHED
)
{
IWL_DEBUG_SCAN
(
mvm
,
"No offloaded scan to stop
\n
"
);
return
;
}
ret
=
iwl_mvm_send_sched_scan_abort
(
mvm
);
if
(
ret
)
IWL_DEBUG_SCAN
(
mvm
,
"Send stop offload scan failed %d
\n
"
,
ret
);
else
IWL_DEBUG_SCAN
(
mvm
,
"Successfully sent stop offload scan
\n
"
);
}
drivers/net/wireless/iwlwifi/mvm/sta.c
浏览文件 @
444474dd
此差异已折叠。
点击以展开。
drivers/net/wireless/iwlwifi/mvm/sta.h
浏览文件 @
444474dd
...
...
@@ -293,10 +293,6 @@ struct iwl_mvm_sta {
struct
iwl_lq_sta
lq_sta
;
struct
ieee80211_vif
*
vif
;
#ifdef CONFIG_PM_SLEEP
u16
last_seq_ctl
;
#endif
/* Temporary, until the new TLC will control the Tx protection */
s8
tx_protection
;
bool
tt_tx_protection
;
...
...
drivers/net/wireless/iwlwifi/mvm/testmode.h
0 → 100644
浏览文件 @
444474dd
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __IWL_MVM_TESTMODE_H__
#define __IWL_MVM_TESTMODE_H__
/**
* enum iwl_mvm_testmode_attrs - testmode attributes inside NL80211_ATTR_TESTDATA
* @IWL_MVM_TM_ATTR_UNSPEC: (invalid attribute)
* @IWL_MVM_TM_ATTR_CMD: sub command, see &enum iwl_mvm_testmode_commands (u32)
* @IWL_MVM_TM_ATTR_NOA_DURATION: requested NoA duration (u32)
* @IWL_MVM_TM_ATTR_BEACON_FILTER_STATE: beacon filter state (0 or 1, u32)
*/
enum
iwl_mvm_testmode_attrs
{
IWL_MVM_TM_ATTR_UNSPEC
,
IWL_MVM_TM_ATTR_CMD
,
IWL_MVM_TM_ATTR_NOA_DURATION
,
IWL_MVM_TM_ATTR_BEACON_FILTER_STATE
,
/* keep last */
NUM_IWL_MVM_TM_ATTRS
,
IWL_MVM_TM_ATTR_MAX
=
NUM_IWL_MVM_TM_ATTRS
-
1
,
};
/**
* enum iwl_mvm_testmode_commands - MVM testmode commands
* @IWL_MVM_TM_CMD_SET_NOA: set NoA on GO vif for testing
* @IWL_MVM_TM_CMD_SET_BEACON_FILTER: turn beacon filtering off/on
*/
enum
iwl_mvm_testmode_commands
{
IWL_MVM_TM_CMD_SET_NOA
,
IWL_MVM_TM_CMD_SET_BEACON_FILTER
,
};
#endif
/* __IWL_MVM_TESTMODE_H__ */
drivers/net/wireless/iwlwifi/mvm/time-event.c
浏览文件 @
444474dd
...
...
@@ -387,7 +387,8 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
void
iwl_mvm_protect_session
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
u32
duration
,
u32
min_duration
)
u32
duration
,
u32
min_duration
,
u32
max_delay
)
{
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
struct
iwl_mvm_time_event_data
*
te_data
=
&
mvmvif
->
time_event_data
;
...
...
@@ -426,7 +427,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
cpu_to_le32
(
iwl_read_prph
(
mvm
->
trans
,
DEVICE_SYSTEM_TIME_REG
));
time_cmd
.
max_frags
=
TE_V2_FRAG_NONE
;
time_cmd
.
max_delay
=
cpu_to_le32
(
500
);
time_cmd
.
max_delay
=
cpu_to_le32
(
max_delay
);
/* TODO: why do we need to interval = bi if it is not periodic? */
time_cmd
.
interval
=
cpu_to_le32
(
1
);
time_cmd
.
duration
=
cpu_to_le32
(
duration
);
...
...
drivers/net/wireless/iwlwifi/mvm/time-event.h
浏览文件 @
444474dd
...
...
@@ -123,6 +123,7 @@
* @duration: the duration of the session in TU.
* @min_duration: will start a new session if the current session will end
* in less than min_duration.
* @max_delay: maximum delay before starting the time event (in TU)
*
* This function can be used to start a session protection which means that the
* fw will stay on the channel for %duration_ms milliseconds. This function
...
...
@@ -133,7 +134,8 @@
*/
void
iwl_mvm_protect_session
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
u32
duration
,
u32
min_duration
);
u32
duration
,
u32
min_duration
,
u32
max_delay
);
/**
* iwl_mvm_stop_session_protection - cancel the session protection.
...
...
drivers/net/wireless/iwlwifi/mvm/tx.c
浏览文件 @
444474dd
...
...
@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
spin_unlock
(
&
mvmsta
->
lock
);
if
(
txq_id
<
IWL_MVM_FIRST_AGG_QUEUE
)
if
(
txq_id
<
mvm
->
first_agg_queue
)
atomic_inc
(
&
mvm
->
pending_frames
[
mvmsta
->
sta_id
]);
return
0
;
...
...
@@ -511,16 +511,10 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status)
}
#endif
/* CONFIG_IWLWIFI_DEBUG */
/**
* translate ucode response to mac80211 tx status control values
*/
static
void
iwl_mvm_hwrate_to_tx_control
(
u32
rate_n_flags
,
struct
ieee80211_tx_info
*
info
)
void
iwl_mvm_hwrate_to_tx_rate
(
u32
rate_n_flags
,
enum
ieee80211_band
band
,
struct
ieee80211_tx_rate
*
r
)
{
struct
ieee80211_tx_rate
*
r
=
&
info
->
status
.
rates
[
0
];
info
->
status
.
antenna
=
((
rate_n_flags
&
RATE_MCS_ANT_ABC_MSK
)
>>
RATE_MCS_ANT_POS
);
if
(
rate_n_flags
&
RATE_HT_MCS_GF_MSK
)
r
->
flags
|=
IEEE80211_TX_RC_GREEN_FIELD
;
switch
(
rate_n_flags
&
RATE_MCS_CHAN_WIDTH_MSK
)
{
...
...
@@ -549,10 +543,23 @@ static void iwl_mvm_hwrate_to_tx_control(u32 rate_n_flags,
r
->
flags
|=
IEEE80211_TX_RC_VHT_MCS
;
}
else
{
r
->
idx
=
iwl_mvm_legacy_rate_to_mac80211_idx
(
rate_n_flags
,
info
->
band
);
band
);
}
}
/**
* translate ucode response to mac80211 tx status control values
*/
static
void
iwl_mvm_hwrate_to_tx_status
(
u32
rate_n_flags
,
struct
ieee80211_tx_info
*
info
)
{
struct
ieee80211_tx_rate
*
r
=
&
info
->
status
.
rates
[
0
];
info
->
status
.
antenna
=
((
rate_n_flags
&
RATE_MCS_ANT_ABC_MSK
)
>>
RATE_MCS_ANT_POS
);
iwl_mvm_hwrate_to_tx_rate
(
rate_n_flags
,
info
->
band
,
r
);
}
static
void
iwl_mvm_rx_tx_cmd_single
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_packet
*
pkt
)
{
...
...
@@ -602,11 +609,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
}
info
->
status
.
rates
[
0
].
count
=
tx_resp
->
failure_frame
+
1
;
iwl_mvm_hwrate_to_tx_
control
(
le32_to_cpu
(
tx_resp
->
initial_rate
),
info
);
iwl_mvm_hwrate_to_tx_
status
(
le32_to_cpu
(
tx_resp
->
initial_rate
),
info
);
/* Single frame failure in an AMPDU queue => send BAR */
if
(
txq_id
>=
IWL_MVM_FIRST_AGG_QUEUE
&&
if
(
txq_id
>=
mvm
->
first_agg_queue
&&
!
(
info
->
flags
&
IEEE80211_TX_STAT_ACK
))
info
->
flags
|=
IEEE80211_TX_STAT_AMPDU_NO_BACK
;
...
...
@@ -619,7 +626,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
ieee80211_tx_status_ni
(
mvm
->
hw
,
skb
);
}
if
(
txq_id
>=
IWL_MVM_FIRST_AGG_QUEUE
)
{
if
(
txq_id
>=
mvm
->
first_agg_queue
)
{
/* If this is an aggregation queue, we use the ssn since:
* ssn = wifi seq_num % 256.
* The seq_ctl is the sequence control of the packet to which
...
...
@@ -668,10 +675,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
iwl_mvm_check_ratid_empty
(
mvm
,
sta
,
tid
);
spin_unlock_bh
(
&
mvmsta
->
lock
);
}
#ifdef CONFIG_PM_SLEEP
mvmsta
->
last_seq_ctl
=
seq_ctl
;
#endif
}
else
{
sta
=
NULL
;
mvmsta
=
NULL
;
...
...
@@ -681,7 +684,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
* If the txq is not an AMPDU queue, there is no chance we freed
* several skbs. Check that out...
*/
if
(
txq_id
<
IWL_MVM_FIRST_AGG_QUEUE
&&
!
WARN_ON
(
skb_freed
>
1
)
&&
if
(
txq_id
<
mvm
->
first_agg_queue
&&
!
WARN_ON
(
skb_freed
>
1
)
&&
atomic_sub_and_test
(
skb_freed
,
&
mvm
->
pending_frames
[
sta_id
]))
{
if
(
mvmsta
)
{
/*
...
...
@@ -777,7 +780,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
u16
sequence
=
le16_to_cpu
(
pkt
->
hdr
.
sequence
);
struct
ieee80211_sta
*
sta
;
if
(
WARN_ON_ONCE
(
SEQ_TO_QUEUE
(
sequence
)
<
IWL_MVM_FIRST_AGG_QUEUE
))
if
(
WARN_ON_ONCE
(
SEQ_TO_QUEUE
(
sequence
)
<
mvm
->
first_agg_queue
))
return
;
if
(
WARN_ON_ONCE
(
tid
==
IWL_TID_NON_QOS
))
...
...
@@ -904,8 +907,8 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
info
->
flags
|=
IEEE80211_TX_STAT_AMPDU
;
info
->
status
.
ampdu_ack_len
=
ba_notif
->
txed_2_done
;
info
->
status
.
ampdu_len
=
ba_notif
->
txed
;
iwl_mvm_hwrate_to_tx_
control
(
tid_data
->
rate_n_flags
,
info
);
iwl_mvm_hwrate_to_tx_
status
(
tid_data
->
rate_n_flags
,
info
);
}
}
...
...
drivers/net/wireless/iwlwifi/mvm/utils.c
浏览文件 @
444474dd
...
...
@@ -466,7 +466,7 @@ void iwl_mvm_dump_sram(struct iwl_mvm *mvm)
ofs
=
img
->
sec
[
IWL_UCODE_SECTION_DATA
].
offset
;
len
=
img
->
sec
[
IWL_UCODE_SECTION_DATA
].
len
;
buf
=
kzalloc
(
len
,
GFP_
KERNEL
);
buf
=
kzalloc
(
len
,
GFP_
ATOMIC
);
if
(
!
buf
)
return
;
...
...
drivers/net/wireless/iwlwifi/pcie/drv.c
浏览文件 @
444474dd
...
...
@@ -258,7 +258,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
#endif
/* CONFIG_IWLDVM */
#if IS_ENABLED(CONFIG_IWLMVM)
/* 7
00
0 Series */
/* 7
26
0 Series */
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4070
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4170
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4060
,
iwl7260_2n_cfg
)},
...
...
@@ -308,6 +308,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{
IWL_PCI_DEVICE
(
0x08B3
,
0x8062
,
iwl3160_n_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B4
,
0x8270
,
iwl3160_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B3
,
0x8470
,
iwl3160_2ac_cfg
)},
/* 7265 Series */
{
IWL_PCI_DEVICE
(
0x095A
,
0x5010
,
iwl7265_2ac_cfg
)},
#endif
/* CONFIG_IWLMVM */
{
0
}
...
...
@@ -349,7 +352,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_drv_stop
(
trans_pcie
->
drv
);
out_free_trans:
iwl_trans_pcie_free
(
iwl_trans
);
pci_set_drvdata
(
pdev
,
NULL
);
return
ret
;
}
...
...
@@ -360,8 +362,6 @@ static void iwl_pci_remove(struct pci_dev *pdev)
iwl_drv_stop
(
trans_pcie
->
drv
);
iwl_trans_pcie_free
(
trans
);
pci_set_drvdata
(
pdev
,
NULL
);
}
#ifdef CONFIG_PM_SLEEP
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
浏览文件 @
444474dd
此差异已折叠。
点击以展开。
drivers/net/wireless/iwlwifi/pcie/tx.c
浏览文件 @
444474dd
...
...
@@ -1539,6 +1539,9 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
"Clearing HCMD_ACTIVE for command %s
\n
"
,
get_cmd_string
(
trans_pcie
,
cmd
->
id
));
ret
=
-
ETIMEDOUT
;
iwl_op_mode_nic_error
(
trans
->
op_mode
);
goto
cancel
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录