Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
aa4a6250
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
aa4a6250
编写于
3月 18, 2014
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
上级
2df3b0b7
a82dda6c
变更
37
隐藏空白更改
内联
并排
Showing
37 changed file
with
1709 addition
and
438 deletion
+1709
-438
drivers/net/wireless/iwlwifi/dvm/main.c
drivers/net/wireless/iwlwifi/dvm/main.c
+3
-1
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-7000.c
+4
-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
+38
-0
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/iwl-fw.h
+16
-0
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-io.c
+2
-2
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-io.h
+2
-0
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+11
-8
drivers/net/wireless/iwlwifi/iwl-op-mode.h
drivers/net/wireless/iwlwifi/iwl-op-mode.h
+6
-5
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl-prph.h
+22
-1
drivers/net/wireless/iwlwifi/mvm/Makefile
drivers/net/wireless/iwlwifi/mvm/Makefile
+2
-2
drivers/net/wireless/iwlwifi/mvm/coex.c
drivers/net/wireless/iwlwifi/mvm/coex.c
+330
-6
drivers/net/wireless/iwlwifi/mvm/constants.h
drivers/net/wireless/iwlwifi/mvm/constants.h
+2
-2
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/d3.c
+33
-162
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+5
-0
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
+95
-15
drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
+4
-0
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+7
-1
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+3
-0
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
+2
-1
drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
+106
-0
drivers/net/wireless/iwlwifi/mvm/led.c
drivers/net/wireless/iwlwifi/mvm/led.c
+2
-0
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+117
-28
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+50
-6
drivers/net/wireless/iwlwifi/mvm/offloading.c
drivers/net/wireless/iwlwifi/mvm/offloading.c
+215
-0
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/ops.c
+221
-11
drivers/net/wireless/iwlwifi/mvm/power.c
drivers/net/wireless/iwlwifi/mvm/power.c
+12
-5
drivers/net/wireless/iwlwifi/mvm/quota.c
drivers/net/wireless/iwlwifi/mvm/quota.c
+1
-22
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rs.c
+49
-39
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/scan.c
+154
-86
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.c
+10
-2
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+6
-10
drivers/net/wireless/iwlwifi/mvm/utils.c
drivers/net/wireless/iwlwifi/mvm/utils.c
+32
-17
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/drv.c
+3
-2
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/internal.h
+2
-0
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/rx.c
+1
-1
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+140
-3
未找到文件。
drivers/net/wireless/iwlwifi/dvm/main.c
浏览文件 @
aa4a6250
...
@@ -2039,7 +2039,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
...
@@ -2039,7 +2039,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
ieee80211_free_txskb
(
priv
->
hw
,
skb
);
ieee80211_free_txskb
(
priv
->
hw
,
skb
);
}
}
static
void
iwl_set_hw_rfkill_state
(
struct
iwl_op_mode
*
op_mode
,
bool
state
)
static
bool
iwl_set_hw_rfkill_state
(
struct
iwl_op_mode
*
op_mode
,
bool
state
)
{
{
struct
iwl_priv
*
priv
=
IWL_OP_MODE_GET_DVM
(
op_mode
);
struct
iwl_priv
*
priv
=
IWL_OP_MODE_GET_DVM
(
op_mode
);
...
@@ -2049,6 +2049,8 @@ static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
...
@@ -2049,6 +2049,8 @@ static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
clear_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
);
clear_bit
(
STATUS_RF_KILL_HW
,
&
priv
->
status
);
wiphy_rfkill_set_hw_state
(
priv
->
hw
->
wiphy
,
state
);
wiphy_rfkill_set_hw_state
(
priv
->
hw
->
wiphy
,
state
);
return
false
;
}
}
static
const
struct
iwl_op_mode_ops
iwl_dvm_ops
=
{
static
const
struct
iwl_op_mode_ops
iwl_dvm_ops
=
{
...
...
drivers/net/wireless/iwlwifi/iwl-7000.c
浏览文件 @
aa4a6250
...
@@ -134,6 +134,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
...
@@ -134,6 +134,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
.
nvm_ver
=
IWL7260_NVM_VERSION
,
.
nvm_ver
=
IWL7260_NVM_VERSION
,
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
host_interrupt_operation_mode
=
true
,
.
host_interrupt_operation_mode
=
true
,
.
lp_xtal_workaround
=
true
,
};
};
const
struct
iwl_cfg
iwl7260_2ac_cfg_high_temp
=
{
const
struct
iwl_cfg
iwl7260_2ac_cfg_high_temp
=
{
...
@@ -145,6 +146,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
...
@@ -145,6 +146,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
high_temp
=
true
,
.
high_temp
=
true
,
.
host_interrupt_operation_mode
=
true
,
.
host_interrupt_operation_mode
=
true
,
.
lp_xtal_workaround
=
true
,
};
};
const
struct
iwl_cfg
iwl7260_2n_cfg
=
{
const
struct
iwl_cfg
iwl7260_2n_cfg
=
{
...
@@ -155,6 +157,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
...
@@ -155,6 +157,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
.
nvm_ver
=
IWL7260_NVM_VERSION
,
.
nvm_ver
=
IWL7260_NVM_VERSION
,
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
host_interrupt_operation_mode
=
true
,
.
host_interrupt_operation_mode
=
true
,
.
lp_xtal_workaround
=
true
,
};
};
const
struct
iwl_cfg
iwl7260_n_cfg
=
{
const
struct
iwl_cfg
iwl7260_n_cfg
=
{
...
@@ -165,6 +168,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
...
@@ -165,6 +168,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
.
nvm_ver
=
IWL7260_NVM_VERSION
,
.
nvm_ver
=
IWL7260_NVM_VERSION
,
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
nvm_calib_ver
=
IWL7260_TX_POWER_VERSION
,
.
host_interrupt_operation_mode
=
true
,
.
host_interrupt_operation_mode
=
true
,
.
lp_xtal_workaround
=
true
,
};
};
const
struct
iwl_cfg
iwl3160_2ac_cfg
=
{
const
struct
iwl_cfg
iwl3160_2ac_cfg
=
{
...
...
drivers/net/wireless/iwlwifi/iwl-config.h
浏览文件 @
aa4a6250
...
@@ -262,6 +262,7 @@ struct iwl_cfg {
...
@@ -262,6 +262,7 @@ struct iwl_cfg {
bool
high_temp
;
bool
high_temp
;
bool
d0i3
;
bool
d0i3
;
u8
nvm_hw_section_num
;
u8
nvm_hw_section_num
;
bool
lp_xtal_workaround
;
const
struct
iwl_pwr_tx_backoff
*
pwr_tx_backoffs
;
const
struct
iwl_pwr_tx_backoff
*
pwr_tx_backoffs
;
};
};
...
...
drivers/net/wireless/iwlwifi/iwl-csr.h
浏览文件 @
aa4a6250
...
@@ -138,6 +138,13 @@
...
@@ -138,6 +138,13 @@
/* Analog phase-lock-loop configuration */
/* Analog phase-lock-loop configuration */
#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
/*
* CSR HW resources monitor registers
*/
#define CSR_MONITOR_CFG_REG (CSR_BASE+0x214)
#define CSR_MONITOR_STATUS_REG (CSR_BASE+0x228)
#define CSR_MONITOR_XTAL_RESOURCES (0x00000010)
/*
/*
* CSR Hardware Revision Workaround Register. Indicates hardware rev;
* CSR Hardware Revision Workaround Register. Indicates hardware rev;
* "step" determines CCK backoff for txpower calculation. Used for 4965 only.
* "step" determines CCK backoff for txpower calculation. Used for 4965 only.
...
@@ -173,6 +180,7 @@
...
@@ -173,6 +180,7 @@
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000)
/* PCI_OWN_SEM */
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000)
/* PCI_OWN_SEM */
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000)
/* ME_OWN */
#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000)
/* ME_OWN */
#define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000)
/* WAKE_ME */
#define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000)
/* WAKE_ME */
#define CSR_HW_IF_CONFIG_REG_PERSIST_MODE (0x40000000)
/* PERSISTENCE */
#define CSR_INT_PERIODIC_DIS (0x00)
/* disable periodic int*/
#define CSR_INT_PERIODIC_DIS (0x00)
/* disable periodic int*/
#define CSR_INT_PERIODIC_ENA (0xFF)
/* 255*32 usec ~ 8 msec*/
#define CSR_INT_PERIODIC_ENA (0xFF)
/* 255*32 usec ~ 8 msec*/
...
@@ -240,6 +248,7 @@
...
@@ -240,6 +248,7 @@
* 001 -- MAC power-down
* 001 -- MAC power-down
* 010 -- PHY (radio) power-down
* 010 -- PHY (radio) power-down
* 011 -- Error
* 011 -- Error
* 10: XTAL ON request
* 9-6: SYS_CONFIG
* 9-6: SYS_CONFIG
* Indicates current system configuration, reflecting pins on chip
* Indicates current system configuration, reflecting pins on chip
* as forced high/low by device circuit board.
* as forced high/low by device circuit board.
...
@@ -271,6 +280,7 @@
...
@@ -271,6 +280,7 @@
#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004)
#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004)
#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008)
#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008)
#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010)
#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010)
#define CSR_GP_CNTRL_REG_FLAG_XTAL_ON (0x00000400)
#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001)
#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001)
...
@@ -395,6 +405,34 @@
...
@@ -395,6 +405,34 @@
#define CSR_DRAM_INT_TBL_ENABLE (1 << 31)
#define CSR_DRAM_INT_TBL_ENABLE (1 << 31)
#define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27)
#define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27)
/*
* SHR target access (Shared block memory space)
*
* Shared internal registers can be accessed directly from PCI bus through SHR
* arbiter without need for the MAC HW to be powered up. This is possible due to
* indirect read/write via HEEP_CTRL_WRD_PCIEX_CTRL (0xEC) and
* HEEP_CTRL_WRD_PCIEX_DATA (0xF4) registers.
*
* Use iwl_write32()/iwl_read32() family to access these registers. The MAC HW
* need not be powered up so no "grab inc access" is required.
*/
/*
* Registers for accessing shared registers (e.g. SHR_APMG_GP1,
* SHR_APMG_XTAL_CFG). For example, to read from SHR_APMG_GP1 register (0x1DC),
* first, write to the control register:
* HEEP_CTRL_WRD_PCIEX_CTRL[15:0] = 0x1DC (offset of the SHR_APMG_GP1 register)
* HEEP_CTRL_WRD_PCIEX_CTRL[29:28] = 2 (read access)
* second, read from the data register HEEP_CTRL_WRD_PCIEX_DATA[31:0].
*
* To write the register, first, write to the data register
* HEEP_CTRL_WRD_PCIEX_DATA[31:0] and then:
* HEEP_CTRL_WRD_PCIEX_CTRL[15:0] = 0x1DC (offset of the SHR_APMG_GP1 register)
* HEEP_CTRL_WRD_PCIEX_CTRL[29:28] = 3 (write access)
*/
#define HEEP_CTRL_WRD_PCIEX_CTRL_REG (CSR_BASE+0x0ec)
#define HEEP_CTRL_WRD_PCIEX_DATA_REG (CSR_BASE+0x0f4)
/*
/*
* HBUS (Host-side Bus)
* HBUS (Host-side Bus)
*
*
...
...
drivers/net/wireless/iwlwifi/iwl-fw.h
浏览文件 @
aa4a6250
...
@@ -125,6 +125,22 @@ enum iwl_ucode_tlv_flag {
...
@@ -125,6 +125,22 @@ enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_GO_UAPSD
=
BIT
(
30
),
IWL_UCODE_TLV_FLAGS_GO_UAPSD
=
BIT
(
30
),
};
};
/**
* enum iwl_ucode_tlv_api - ucode api
* @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
*/
enum
iwl_ucode_tlv_api
{
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID
=
BIT
(
0
),
};
/**
* enum iwl_ucode_tlv_capa - ucode capabilities
* @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
*/
enum
iwl_ucode_tlv_capa
{
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT
=
BIT
(
0
),
};
/* The default calibrate table size if not specified by firmware file */
/* The default calibrate table size if not specified by firmware file */
#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
...
...
drivers/net/wireless/iwlwifi/iwl-io.c
浏览文件 @
aa4a6250
...
@@ -93,14 +93,14 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
...
@@ -93,14 +93,14 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
}
}
IWL_EXPORT_SYMBOL
(
iwl_poll_direct_bit
);
IWL_EXPORT_SYMBOL
(
iwl_poll_direct_bit
);
static
inline
u32
__iwl_read_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
)
u32
__iwl_read_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
)
{
{
u32
val
=
iwl_trans_read_prph
(
trans
,
ofs
);
u32
val
=
iwl_trans_read_prph
(
trans
,
ofs
);
trace_iwlwifi_dev_ioread_prph32
(
trans
->
dev
,
ofs
,
val
);
trace_iwlwifi_dev_ioread_prph32
(
trans
->
dev
,
ofs
,
val
);
return
val
;
return
val
;
}
}
static
inline
void
__iwl_write_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
,
u32
val
)
void
__iwl_write_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
,
u32
val
)
{
{
trace_iwlwifi_dev_iowrite_prph32
(
trans
->
dev
,
ofs
,
val
);
trace_iwlwifi_dev_iowrite_prph32
(
trans
->
dev
,
ofs
,
val
);
iwl_trans_write_prph
(
trans
,
ofs
,
val
);
iwl_trans_write_prph
(
trans
,
ofs
,
val
);
...
...
drivers/net/wireless/iwlwifi/iwl-io.h
浏览文件 @
aa4a6250
...
@@ -70,7 +70,9 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
...
@@ -70,7 +70,9 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
void
iwl_write_direct32
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
value
);
void
iwl_write_direct32
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
value
);
u32
__iwl_read_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
);
u32
iwl_read_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
);
u32
iwl_read_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
);
void
__iwl_write_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
,
u32
val
);
void
iwl_write_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
,
u32
val
);
void
iwl_write_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
,
u32
val
);
int
iwl_poll_prph_bit
(
struct
iwl_trans
*
trans
,
u32
addr
,
int
iwl_poll_prph_bit
(
struct
iwl_trans
*
trans
,
u32
addr
,
u32
bits
,
u32
mask
,
int
timeout
);
u32
bits
,
u32
mask
,
int
timeout
);
...
...
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
浏览文件 @
aa4a6250
...
@@ -299,9 +299,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
...
@@ -299,9 +299,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
static
void
iwl_init_vht_hw_capab
(
const
struct
iwl_cfg
*
cfg
,
static
void
iwl_init_vht_hw_capab
(
const
struct
iwl_cfg
*
cfg
,
struct
iwl_nvm_data
*
data
,
struct
iwl_nvm_data
*
data
,
struct
ieee80211_sta_vht_cap
*
vht_cap
)
struct
ieee80211_sta_vht_cap
*
vht_cap
,
u8
tx_chains
,
u8
rx_chains
)
{
{
int
num_ants
=
num_of_ant
(
data
->
valid_rx_ant
);
int
num_rx_ants
=
num_of_ant
(
rx_chains
);
int
num_tx_ants
=
num_of_ant
(
tx_chains
);
vht_cap
->
vht_supported
=
true
;
vht_cap
->
vht_supported
=
true
;
...
@@ -311,8 +313,10 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
...
@@ -311,8 +313,10 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
3
<<
IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT
|
3
<<
IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT
|
7
<<
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT
;
7
<<
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT
;
if
(
num_ants
>
1
)
if
(
num_
tx_
ants
>
1
)
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_TXSTBC
;
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_TXSTBC
;
else
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN
;
if
(
iwlwifi_mod_params
.
amsdu_size_8K
)
if
(
iwlwifi_mod_params
.
amsdu_size_8K
)
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991
;
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991
;
...
@@ -327,10 +331,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
...
@@ -327,10 +331,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
IEEE80211_VHT_MCS_NOT_SUPPORTED
<<
12
|
IEEE80211_VHT_MCS_NOT_SUPPORTED
<<
12
|
IEEE80211_VHT_MCS_NOT_SUPPORTED
<<
14
);
IEEE80211_VHT_MCS_NOT_SUPPORTED
<<
14
);
if
(
num_ants
==
1
||
if
(
num_rx_ants
==
1
||
cfg
->
rx_with_siso_diversity
)
{
cfg
->
rx_with_siso_diversity
)
{
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN
;
vht_cap
->
cap
|=
IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN
|
IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN
;
/* this works because NOT_SUPPORTED == 3 */
/* this works because NOT_SUPPORTED == 3 */
vht_cap
->
vht_mcs
.
rx_mcs_map
|=
vht_cap
->
vht_mcs
.
rx_mcs_map
|=
cpu_to_le16
(
IEEE80211_VHT_MCS_NOT_SUPPORTED
<<
2
);
cpu_to_le16
(
IEEE80211_VHT_MCS_NOT_SUPPORTED
<<
2
);
...
@@ -375,7 +377,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
...
@@ -375,7 +377,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
iwl_init_ht_hw_capab
(
cfg
,
data
,
&
sband
->
ht_cap
,
IEEE80211_BAND_5GHZ
,
iwl_init_ht_hw_capab
(
cfg
,
data
,
&
sband
->
ht_cap
,
IEEE80211_BAND_5GHZ
,
tx_chains
,
rx_chains
);
tx_chains
,
rx_chains
);
if
(
enable_vht
)
if
(
enable_vht
)
iwl_init_vht_hw_capab
(
cfg
,
data
,
&
sband
->
vht_cap
);
iwl_init_vht_hw_capab
(
cfg
,
data
,
&
sband
->
vht_cap
,
tx_chains
,
rx_chains
);
if
(
n_channels
!=
n_used
)
if
(
n_channels
!=
n_used
)
IWL_ERR_DEV
(
dev
,
"NVM: used only %d of %d channels
\n
"
,
IWL_ERR_DEV
(
dev
,
"NVM: used only %d of %d channels
\n
"
,
...
...
drivers/net/wireless/iwlwifi/iwl-op-mode.h
浏览文件 @
aa4a6250
...
@@ -119,7 +119,8 @@ struct iwl_cfg;
...
@@ -119,7 +119,8 @@ struct iwl_cfg;
* @queue_not_full: notifies that a HW queue is not full any more.
* @queue_not_full: notifies that a HW queue is not full any more.
* Must be atomic and called with BH disabled.
* Must be atomic and called with BH disabled.
* @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
* @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
* the radio is killed. May sleep.
* the radio is killed. Return %true if the device should be stopped by
* the transport immediately after the call. May sleep.
* @free_skb: allows the transport layer to free skbs that haven't been
* @free_skb: allows the transport layer to free skbs that haven't been
* reclaimed by the op_mode. This can happen when the driver is freed and
* reclaimed by the op_mode. This can happen when the driver is freed and
* there are Tx packets pending in the transport layer.
* there are Tx packets pending in the transport layer.
...
@@ -144,7 +145,7 @@ struct iwl_op_mode_ops {
...
@@ -144,7 +145,7 @@ struct iwl_op_mode_ops {
struct
iwl_device_cmd
*
cmd
);
struct
iwl_device_cmd
*
cmd
);
void
(
*
queue_full
)(
struct
iwl_op_mode
*
op_mode
,
int
queue
);
void
(
*
queue_full
)(
struct
iwl_op_mode
*
op_mode
,
int
queue
);
void
(
*
queue_not_full
)(
struct
iwl_op_mode
*
op_mode
,
int
queue
);
void
(
*
queue_not_full
)(
struct
iwl_op_mode
*
op_mode
,
int
queue
);
void
(
*
hw_rf_kill
)(
struct
iwl_op_mode
*
op_mode
,
bool
state
);
bool
(
*
hw_rf_kill
)(
struct
iwl_op_mode
*
op_mode
,
bool
state
);
void
(
*
free_skb
)(
struct
iwl_op_mode
*
op_mode
,
struct
sk_buff
*
skb
);
void
(
*
free_skb
)(
struct
iwl_op_mode
*
op_mode
,
struct
sk_buff
*
skb
);
void
(
*
nic_error
)(
struct
iwl_op_mode
*
op_mode
);
void
(
*
nic_error
)(
struct
iwl_op_mode
*
op_mode
);
void
(
*
cmd_queue_full
)(
struct
iwl_op_mode
*
op_mode
);
void
(
*
cmd_queue_full
)(
struct
iwl_op_mode
*
op_mode
);
...
@@ -195,11 +196,11 @@ static inline void iwl_op_mode_queue_not_full(struct iwl_op_mode *op_mode,
...
@@ -195,11 +196,11 @@ static inline void iwl_op_mode_queue_not_full(struct iwl_op_mode *op_mode,
op_mode
->
ops
->
queue_not_full
(
op_mode
,
queue
);
op_mode
->
ops
->
queue_not_full
(
op_mode
,
queue
);
}
}
static
inline
void
iwl_op_mode_hw_rf_kill
(
struct
iwl_op_mode
*
op_mode
,
static
inline
bool
__must_check
bool
state
)
iwl_op_mode_hw_rf_kill
(
struct
iwl_op_mode
*
op_mode
,
bool
state
)
{
{
might_sleep
();
might_sleep
();
op_mode
->
ops
->
hw_rf_kill
(
op_mode
,
state
);
return
op_mode
->
ops
->
hw_rf_kill
(
op_mode
,
state
);
}
}
static
inline
void
iwl_op_mode_free_skb
(
struct
iwl_op_mode
*
op_mode
,
static
inline
void
iwl_op_mode_free_skb
(
struct
iwl_op_mode
*
op_mode
,
...
...
drivers/net/wireless/iwlwifi/iwl-prph.h
浏览文件 @
aa4a6250
...
@@ -95,7 +95,8 @@
...
@@ -95,7 +95,8 @@
#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0)
/* bit 8:5 */
#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0)
/* bit 8:5 */
#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060)
#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060)
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
#define APMG_PCIDEV_STT_VAL_PERSIST_DIS (0x00000200)
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
#define APMG_RTC_INT_STT_RFKILL (0x10000000)
#define APMG_RTC_INT_STT_RFKILL (0x10000000)
...
@@ -105,6 +106,26 @@
...
@@ -105,6 +106,26 @@
/* Device NMI register */
/* Device NMI register */
#define DEVICE_SET_NMI_REG 0x00a01c30
#define DEVICE_SET_NMI_REG 0x00a01c30
/* Shared registers (0x0..0x3ff, via target indirect or periphery */
#define SHR_BASE 0x00a10000
/* Shared GP1 register */
#define SHR_APMG_GP1_REG 0x01dc
#define SHR_APMG_GP1_REG_PRPH (SHR_BASE + SHR_APMG_GP1_REG)
#define SHR_APMG_GP1_WF_XTAL_LP_EN 0x00000004
#define SHR_APMG_GP1_CHICKEN_BIT_SELECT 0x80000000
/* Shared DL_CFG register */
#define SHR_APMG_DL_CFG_REG 0x01c4
#define SHR_APMG_DL_CFG_REG_PRPH (SHR_BASE + SHR_APMG_DL_CFG_REG)
#define SHR_APMG_DL_CFG_RTCS_CLK_SELECTOR_MSK 0x000000c0
#define SHR_APMG_DL_CFG_RTCS_CLK_INTERNAL_XTAL 0x00000080
#define SHR_APMG_DL_CFG_DL_CLOCK_POWER_UP 0x00000100
/* Shared APMG_XTAL_CFG register */
#define SHR_APMG_XTAL_CFG_REG 0x1c0
#define SHR_APMG_XTAL_CFG_XTAL_ON_REQ 0x80000000
/*
/*
* Device reset for family 8000
* Device reset for family 8000
* write to bit 24 in order to reset the CPU
* write to bit 24 in order to reset the CPU
...
...
drivers/net/wireless/iwlwifi/mvm/Makefile
浏览文件 @
aa4a6250
...
@@ -2,8 +2,8 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
...
@@ -2,8 +2,8 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
iwlmvm-y
+=
fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
iwlmvm-y
+=
fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
iwlmvm-y
+=
utils.o rx.o tx.o binding.o quota.o sta.o sf.o
iwlmvm-y
+=
utils.o rx.o tx.o binding.o quota.o sta.o sf.o
iwlmvm-y
+=
scan.o time-event.o rs.o
iwlmvm-y
+=
scan.o time-event.o rs.o
iwlmvm-y
+=
power.o
bt-
coex.o
iwlmvm-y
+=
power.o coex.o
iwlmvm-y
+=
led.o tt.o
iwlmvm-y
+=
led.o tt.o
offloading.o
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS)
+=
debugfs.o debugfs-vif.o
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS)
+=
debugfs.o debugfs-vif.o
iwlmvm-$(CONFIG_PM_SLEEP)
+=
d3.o
iwlmvm-$(CONFIG_PM_SLEEP)
+=
d3.o
...
...
drivers/net/wireless/iwlwifi/mvm/
bt-
coex.c
→
drivers/net/wireless/iwlwifi/mvm/coex.c
浏览文件 @
aa4a6250
...
@@ -61,9 +61,11 @@
...
@@ -61,9 +61,11 @@
*
*
*****************************************************************************/
*****************************************************************************/
#include <linux/ieee80211.h>
#include <linux/etherdevice.h>
#include <net/mac80211.h>
#include <net/mac80211.h>
#include "fw-api-
bt-
coex.h"
#include "fw-api-coex.h"
#include "iwl-modparams.h"
#include "iwl-modparams.h"
#include "mvm.h"
#include "mvm.h"
#include "iwl-debug.h"
#include "iwl-debug.h"
...
@@ -305,6 +307,215 @@ static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
...
@@ -305,6 +307,215 @@ static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
cpu_to_le32
(
0x33113311
),
cpu_to_le32
(
0x33113311
),
};
};
struct
corunning_block_luts
{
u8
range
;
__le32
lut20
[
BT_COEX_CORUN_LUT_SIZE
];
};
/*
* Ranges for the antenna coupling calibration / co-running block LUT:
* LUT0: [ 0, 12[
* LUT1: [12, 20[
* LUT2: [20, 21[
* LUT3: [21, 23[
* LUT4: [23, 27[
* LUT5: [27, 30[
* LUT6: [30, 32[
* LUT7: [32, 33[
* LUT8: [33, - [
*/
static
const
struct
corunning_block_luts
antenna_coupling_ranges
[]
=
{
{
.
range
=
0
,
.
lut20
=
{
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
12
,
.
lut20
=
{
cpu_to_le32
(
0x00000001
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
20
,
.
lut20
=
{
cpu_to_le32
(
0x00000002
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
21
,
.
lut20
=
{
cpu_to_le32
(
0x00000003
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
23
,
.
lut20
=
{
cpu_to_le32
(
0x00000004
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
27
,
.
lut20
=
{
cpu_to_le32
(
0x00000005
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
30
,
.
lut20
=
{
cpu_to_le32
(
0x00000006
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
32
,
.
lut20
=
{
cpu_to_le32
(
0x00000007
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
{
.
range
=
33
,
.
lut20
=
{
cpu_to_le32
(
0x00000008
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
cpu_to_le32
(
0x00000000
),
},
},
};
static
enum
iwl_bt_coex_lut_type
static
enum
iwl_bt_coex_lut_type
iwl_get_coex_type
(
struct
iwl_mvm
*
mvm
,
const
struct
ieee80211_vif
*
vif
)
iwl_get_coex_type
(
struct
iwl_mvm
*
mvm
,
const
struct
ieee80211_vif
*
vif
)
{
{
...
@@ -390,8 +601,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
...
@@ -390,8 +601,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
BT_VALID_LUT
|
BT_VALID_LUT
|
BT_VALID_WIFI_RX_SW_PRIO_BOOST
|
BT_VALID_WIFI_RX_SW_PRIO_BOOST
|
BT_VALID_WIFI_TX_SW_PRIO_BOOST
|
BT_VALID_WIFI_TX_SW_PRIO_BOOST
|
BT_VALID_CORUN_LUT_20
|
BT_VALID_CORUN_LUT_40
|
BT_VALID_ANT_ISOLATION
|
BT_VALID_ANT_ISOLATION
|
BT_VALID_ANT_ISOLATION_THRS
|
BT_VALID_ANT_ISOLATION_THRS
|
BT_VALID_TXTX_DELTA_FREQ_THRS
|
BT_VALID_TXTX_DELTA_FREQ_THRS
|
...
@@ -401,6 +610,17 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
...
@@ -401,6 +610,17 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
if
(
IWL_MVM_BT_COEX_SYNC2SCO
)
if
(
IWL_MVM_BT_COEX_SYNC2SCO
)
bt_cmd
->
flags
|=
cpu_to_le32
(
BT_COEX_SYNC2SCO
);
bt_cmd
->
flags
|=
cpu_to_le32
(
BT_COEX_SYNC2SCO
);
if
(
IWL_MVM_BT_COEX_CORUNNING
)
{
bt_cmd
->
valid_bit_msk
=
cpu_to_le32
(
BT_VALID_CORUN_LUT_20
|
BT_VALID_CORUN_LUT_40
);
bt_cmd
->
flags
|=
cpu_to_le32
(
BT_COEX_CORUNNING
);
}
if
(
IWL_MVM_BT_COEX_MPLUT
)
{
bt_cmd
->
flags
|=
cpu_to_le32
(
BT_COEX_MPLUT
);
bt_cmd
->
valid_bit_msk
=
cpu_to_le32
(
BT_VALID_MULTI_PRIO_LUT
);
}
if
(
mvm
->
cfg
->
bt_shared_single_ant
)
if
(
mvm
->
cfg
->
bt_shared_single_ant
)
memcpy
(
&
bt_cmd
->
decision_lut
,
iwl_single_shared_ant
,
memcpy
(
&
bt_cmd
->
decision_lut
,
iwl_single_shared_ant
,
sizeof
(
iwl_single_shared_ant
));
sizeof
(
iwl_single_shared_ant
));
...
@@ -408,6 +628,12 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
...
@@ -408,6 +628,12 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
memcpy
(
&
bt_cmd
->
decision_lut
,
iwl_combined_lookup
,
memcpy
(
&
bt_cmd
->
decision_lut
,
iwl_combined_lookup
,
sizeof
(
iwl_combined_lookup
));
sizeof
(
iwl_combined_lookup
));
/* Take first Co-running block LUT to get started */
memcpy
(
bt_cmd
->
bt4_corun_lut20
,
antenna_coupling_ranges
[
0
].
lut20
,
sizeof
(
bt_cmd
->
bt4_corun_lut20
));
memcpy
(
bt_cmd
->
bt4_corun_lut40
,
antenna_coupling_ranges
[
0
].
lut20
,
sizeof
(
bt_cmd
->
bt4_corun_lut40
));
memcpy
(
&
bt_cmd
->
bt_prio_boost
,
iwl_bt_prio_boost
,
memcpy
(
&
bt_cmd
->
bt_prio_boost
,
iwl_bt_prio_boost
,
sizeof
(
iwl_bt_prio_boost
));
sizeof
(
iwl_bt_prio_boost
));
memcpy
(
&
bt_cmd
->
bt4_multiprio_lut
,
iwl_bt_mprio_lut
,
memcpy
(
&
bt_cmd
->
bt4_multiprio_lut
,
iwl_bt_mprio_lut
,
...
@@ -498,7 +724,7 @@ int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, bool enable)
...
@@ -498,7 +724,7 @@ int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, bool enable)
struct
iwl_host_cmd
cmd
=
{
struct
iwl_host_cmd
cmd
=
{
.
id
=
BT_CONFIG
,
.
id
=
BT_CONFIG
,
.
len
=
{
sizeof
(
*
bt_cmd
),
},
.
len
=
{
sizeof
(
*
bt_cmd
),
},
.
dataflags
=
{
IWL_HCMD_DFL_
DUP
,
},
.
dataflags
=
{
IWL_HCMD_DFL_
NOCOPY
,
},
.
flags
=
CMD_ASYNC
,
.
flags
=
CMD_ASYNC
,
};
};
struct
iwl_mvm_sta
*
mvmsta
;
struct
iwl_mvm_sta
*
mvmsta
;
...
@@ -952,8 +1178,8 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...
@@ -952,8 +1178,8 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000)
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000)
#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200)
#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200)
u16
iwl_mvm_
bt_
coex_agg_time_limit
(
struct
iwl_mvm
*
mvm
,
u16
iwl_mvm_coex_agg_time_limit
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
)
struct
ieee80211_sta
*
sta
)
{
{
struct
iwl_mvm_sta
*
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
struct
iwl_mvm_sta
*
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
enum
iwl_bt_coex_lut_type
lut_type
;
enum
iwl_bt_coex_lut_type
lut_type
;
...
@@ -989,6 +1215,38 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
...
@@ -989,6 +1215,38 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
return
iwl_get_coex_type
(
mvm
,
mvmsta
->
vif
)
==
BT_COEX_TIGHT_LUT
;
return
iwl_get_coex_type
(
mvm
,
mvmsta
->
vif
)
==
BT_COEX_TIGHT_LUT
;
}
}
u8
iwl_mvm_bt_coex_tx_prio
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_hdr
*
hdr
,
struct
ieee80211_tx_info
*
info
,
u8
ac
)
{
__le16
fc
=
hdr
->
frame_control
;
if
(
info
->
band
!=
IEEE80211_BAND_2GHZ
)
return
0
;
if
(
unlikely
(
mvm
->
bt_tx_prio
))
return
mvm
->
bt_tx_prio
-
1
;
/* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
if
(
info
->
control
.
flags
&
IEEE80211_TX_CTRL_PORT_CTRL_PROTO
||
is_multicast_ether_addr
(
hdr
->
addr1
)
||
ieee80211_is_ctl
(
fc
)
||
ieee80211_is_mgmt
(
fc
)
||
ieee80211_is_nullfunc
(
fc
)
||
ieee80211_is_qos_nullfunc
(
fc
))
return
3
;
switch
(
ac
)
{
case
IEEE80211_AC_BE
:
return
1
;
case
IEEE80211_AC_VO
:
return
3
;
case
IEEE80211_AC_VI
:
return
2
;
default:
break
;
}
return
0
;
}
void
iwl_mvm_bt_coex_vif_change
(
struct
iwl_mvm
*
mvm
)
void
iwl_mvm_bt_coex_vif_change
(
struct
iwl_mvm
*
mvm
)
{
{
if
(
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NEWBT_COEX
))
if
(
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NEWBT_COEX
))
...
@@ -996,3 +1254,69 @@ void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
...
@@ -996,3 +1254,69 @@ void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
iwl_mvm_bt_coex_notif_handle
(
mvm
);
iwl_mvm_bt_coex_notif_handle
(
mvm
);
}
}
int
iwl_mvm_rx_ant_coupling_notif
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
dev_cmd
)
{
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
u32
ant_isolation
=
le32_to_cpup
((
void
*
)
pkt
->
data
);
u8
__maybe_unused
lower_bound
,
upper_bound
;
u8
lut
;
struct
iwl_bt_coex_cmd
*
bt_cmd
;
struct
iwl_host_cmd
cmd
=
{
.
id
=
BT_CONFIG
,
.
len
=
{
sizeof
(
*
bt_cmd
),
},
.
dataflags
=
{
IWL_HCMD_DFL_NOCOPY
,
},
.
flags
=
CMD_SYNC
,
};
if
(
!
IWL_MVM_BT_COEX_CORUNNING
)
return
0
;
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
ant_isolation
==
mvm
->
last_ant_isol
)
return
0
;
for
(
lut
=
0
;
lut
<
ARRAY_SIZE
(
antenna_coupling_ranges
)
-
1
;
lut
++
)
if
(
ant_isolation
<
antenna_coupling_ranges
[
lut
+
1
].
range
)
break
;
lower_bound
=
antenna_coupling_ranges
[
lut
].
range
;
if
(
lut
<
ARRAY_SIZE
(
antenna_coupling_ranges
)
-
1
)
upper_bound
=
antenna_coupling_ranges
[
lut
+
1
].
range
;
else
upper_bound
=
antenna_coupling_ranges
[
lut
].
range
;
IWL_DEBUG_COEX
(
mvm
,
"Antenna isolation=%d in range [%d,%d[, lut=%d
\n
"
,
ant_isolation
,
lower_bound
,
upper_bound
,
lut
);
mvm
->
last_ant_isol
=
ant_isolation
;
if
(
mvm
->
last_corun_lut
==
lut
)
return
0
;
mvm
->
last_corun_lut
=
lut
;
bt_cmd
=
kzalloc
(
sizeof
(
*
bt_cmd
),
GFP_KERNEL
);
if
(
!
bt_cmd
)
return
0
;
cmd
.
data
[
0
]
=
bt_cmd
;
bt_cmd
->
flags
=
cpu_to_le32
(
BT_COEX_NW
);
bt_cmd
->
valid_bit_msk
|=
cpu_to_le32
(
BT_VALID_ENABLE
|
BT_VALID_CORUN_LUT_20
|
BT_VALID_CORUN_LUT_40
);
/* For the moment, use the same LUT for 20GHz and 40GHz */
memcpy
(
bt_cmd
->
bt4_corun_lut20
,
antenna_coupling_ranges
[
lut
].
lut20
,
sizeof
(
bt_cmd
->
bt4_corun_lut20
));
memcpy
(
bt_cmd
->
bt4_corun_lut40
,
antenna_coupling_ranges
[
lut
].
lut20
,
sizeof
(
bt_cmd
->
bt4_corun_lut40
));
return
0
;
}
drivers/net/wireless/iwlwifi/mvm/constants.h
浏览文件 @
aa4a6250
...
@@ -79,8 +79,8 @@
...
@@ -79,8 +79,8 @@
#define IWL_MVM_PS_SNOOZE_WINDOW 50
#define IWL_MVM_PS_SNOOZE_WINDOW 50
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
#define IWL_MVM_LOWLAT_SINGLE_BINDING_MAXDUR 24
/* TU */
#define IWL_MVM_LOWLAT_DUAL_BINDING_MAXDUR 24
/* TU */
#define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING 1
#define IWL_MVM_BT_COEX_MPLUT 1
#endif
/* __MVM_CONSTANTS_H */
#endif
/* __MVM_CONSTANTS_H */
drivers/net/wireless/iwlwifi/mvm/d3.c
浏览文件 @
aa4a6250
...
@@ -376,139 +376,6 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
...
@@ -376,139 +376,6 @@ static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
return
err
;
return
err
;
}
}
static
int
iwl_mvm_send_proto_offload
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
)
{
union
{
struct
iwl_proto_offload_cmd_v1
v1
;
struct
iwl_proto_offload_cmd_v2
v2
;
struct
iwl_proto_offload_cmd_v3_small
v3s
;
struct
iwl_proto_offload_cmd_v3_large
v3l
;
}
cmd
=
{};
struct
iwl_host_cmd
hcmd
=
{
.
id
=
PROT_OFFLOAD_CONFIG_CMD
,
.
flags
=
CMD_SYNC
,
.
data
[
0
]
=
&
cmd
,
.
dataflags
[
0
]
=
IWL_HCMD_DFL_DUP
,
};
struct
iwl_proto_offload_cmd_common
*
common
;
u32
enabled
=
0
,
size
;
u32
capa_flags
=
mvm
->
fw
->
ucode_capa
.
flags
;
#if IS_ENABLED(CONFIG_IPV6)
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
int
i
;
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
||
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE
)
{
struct
iwl_ns_config
*
nsc
;
struct
iwl_targ_addr
*
addrs
;
int
n_nsc
,
n_addrs
;
int
c
;
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
)
{
nsc
=
cmd
.
v3s
.
ns_config
;
n_nsc
=
IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S
;
addrs
=
cmd
.
v3s
.
targ_addrs
;
n_addrs
=
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S
;
}
else
{
nsc
=
cmd
.
v3l
.
ns_config
;
n_nsc
=
IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L
;
addrs
=
cmd
.
v3l
.
targ_addrs
;
n_addrs
=
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L
;
}
if
(
mvmvif
->
num_target_ipv6_addrs
)
enabled
|=
IWL_D3_PROTO_OFFLOAD_NS
;
/*
* For each address we have (and that will fit) fill a target
* address struct and combine for NS offload structs with the
* solicited node addresses.
*/
for
(
i
=
0
,
c
=
0
;
i
<
mvmvif
->
num_target_ipv6_addrs
&&
i
<
n_addrs
&&
c
<
n_nsc
;
i
++
)
{
struct
in6_addr
solicited_addr
;
int
j
;
addrconf_addr_solict_mult
(
&
mvmvif
->
target_ipv6_addrs
[
i
],
&
solicited_addr
);
for
(
j
=
0
;
j
<
c
;
j
++
)
if
(
ipv6_addr_cmp
(
&
nsc
[
j
].
dest_ipv6_addr
,
&
solicited_addr
)
==
0
)
break
;
if
(
j
==
c
)
c
++
;
addrs
[
i
].
addr
=
mvmvif
->
target_ipv6_addrs
[
i
];
addrs
[
i
].
config_num
=
cpu_to_le32
(
j
);
nsc
[
j
].
dest_ipv6_addr
=
solicited_addr
;
memcpy
(
nsc
[
j
].
target_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
)
cmd
.
v3s
.
num_valid_ipv6_addrs
=
cpu_to_le32
(
i
);
else
cmd
.
v3l
.
num_valid_ipv6_addrs
=
cpu_to_le32
(
i
);
}
else
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS
)
{
if
(
mvmvif
->
num_target_ipv6_addrs
)
{
enabled
|=
IWL_D3_PROTO_OFFLOAD_NS
;
memcpy
(
cmd
.
v2
.
ndp_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
BUILD_BUG_ON
(
sizeof
(
cmd
.
v2
.
target_ipv6_addr
[
0
])
!=
sizeof
(
mvmvif
->
target_ipv6_addrs
[
0
]));
for
(
i
=
0
;
i
<
min
(
mvmvif
->
num_target_ipv6_addrs
,
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2
);
i
++
)
memcpy
(
cmd
.
v2
.
target_ipv6_addr
[
i
],
&
mvmvif
->
target_ipv6_addrs
[
i
],
sizeof
(
cmd
.
v2
.
target_ipv6_addr
[
i
]));
}
else
{
if
(
mvmvif
->
num_target_ipv6_addrs
)
{
enabled
|=
IWL_D3_PROTO_OFFLOAD_NS
;
memcpy
(
cmd
.
v1
.
ndp_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
BUILD_BUG_ON
(
sizeof
(
cmd
.
v1
.
target_ipv6_addr
[
0
])
!=
sizeof
(
mvmvif
->
target_ipv6_addrs
[
0
]));
for
(
i
=
0
;
i
<
min
(
mvmvif
->
num_target_ipv6_addrs
,
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1
);
i
++
)
memcpy
(
cmd
.
v1
.
target_ipv6_addr
[
i
],
&
mvmvif
->
target_ipv6_addrs
[
i
],
sizeof
(
cmd
.
v1
.
target_ipv6_addr
[
i
]));
}
#endif
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
)
{
common
=
&
cmd
.
v3s
.
common
;
size
=
sizeof
(
cmd
.
v3s
);
}
else
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE
)
{
common
=
&
cmd
.
v3l
.
common
;
size
=
sizeof
(
cmd
.
v3l
);
}
else
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS
)
{
common
=
&
cmd
.
v2
.
common
;
size
=
sizeof
(
cmd
.
v2
);
}
else
{
common
=
&
cmd
.
v1
.
common
;
size
=
sizeof
(
cmd
.
v1
);
}
if
(
vif
->
bss_conf
.
arp_addr_cnt
)
{
enabled
|=
IWL_D3_PROTO_OFFLOAD_ARP
;
common
->
host_ipv4_addr
=
vif
->
bss_conf
.
arp_addr_list
[
0
];
memcpy
(
common
->
arp_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
if
(
!
enabled
)
return
0
;
common
->
enabled
=
cpu_to_le32
(
enabled
);
hcmd
.
len
[
0
]
=
size
;
return
iwl_mvm_send_cmd
(
mvm
,
&
hcmd
);
}
enum
iwl_mvm_tcp_packet_type
{
enum
iwl_mvm_tcp_packet_type
{
MVM_TCP_TX_SYN
,
MVM_TCP_TX_SYN
,
MVM_TCP_RX_SYNACK
,
MVM_TCP_RX_SYNACK
,
...
@@ -846,8 +713,8 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...
@@ -846,8 +713,8 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
quota_cmd
.
quotas
[
0
].
id_and_color
=
quota_cmd
.
quotas
[
0
].
id_and_color
=
cpu_to_le32
(
FW_CMD_ID_AND_COLOR
(
mvmvif
->
phy_ctxt
->
id
,
cpu_to_le32
(
FW_CMD_ID_AND_COLOR
(
mvmvif
->
phy_ctxt
->
id
,
mvmvif
->
phy_ctxt
->
color
));
mvmvif
->
phy_ctxt
->
color
));
quota_cmd
.
quotas
[
0
].
quota
=
cpu_to_le32
(
100
);
quota_cmd
.
quotas
[
0
].
quota
=
cpu_to_le32
(
IWL_MVM_MAX_QUOTA
);
quota_cmd
.
quotas
[
0
].
max_duration
=
cpu_to_le32
(
1000
);
quota_cmd
.
quotas
[
0
].
max_duration
=
cpu_to_le32
(
IWL_MVM_MAX_QUOTA
);
for
(
i
=
1
;
i
<
MAX_BINDINGS
;
i
++
)
for
(
i
=
1
;
i
<
MAX_BINDINGS
;
i
++
)
quota_cmd
.
quotas
[
i
].
id_and_color
=
cpu_to_le32
(
FW_CTXT_INVALID
);
quota_cmd
.
quotas
[
i
].
id_and_color
=
cpu_to_le32
(
FW_CTXT_INVALID
);
...
@@ -927,6 +794,20 @@ void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
...
@@ -927,6 +794,20 @@ void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
IWL_ERR
(
mvm
,
"failed to set non-QoS seqno
\n
"
);
IWL_ERR
(
mvm
,
"failed to set non-QoS seqno
\n
"
);
}
}
static
int
iwl_mvm_send_wowlan_config_cmd
(
struct
iwl_mvm
*
mvm
,
const
struct
iwl_wowlan_config_cmd_v3
*
cmd
)
{
/* start only with the v2 part of the command */
u16
cmd_len
=
sizeof
(
cmd
->
common
);
if
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID
)
cmd_len
=
sizeof
(
*
cmd
);
return
iwl_mvm_send_cmd_pdu
(
mvm
,
WOWLAN_CONFIGURATION
,
CMD_SYNC
,
cmd_len
,
cmd
);
}
static
int
__iwl_mvm_suspend
(
struct
ieee80211_hw
*
hw
,
static
int
__iwl_mvm_suspend
(
struct
ieee80211_hw
*
hw
,
struct
cfg80211_wowlan
*
wowlan
,
struct
cfg80211_wowlan
*
wowlan
,
bool
test
)
bool
test
)
...
@@ -939,7 +820,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
...
@@ -939,7 +820,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
struct
iwl_mvm_vif
*
mvmvif
;
struct
iwl_mvm_vif
*
mvmvif
;
struct
ieee80211_sta
*
ap_sta
;
struct
ieee80211_sta
*
ap_sta
;
struct
iwl_mvm_sta
*
mvm_ap_sta
;
struct
iwl_mvm_sta
*
mvm_ap_sta
;
struct
iwl_wowlan_config_cmd
wowlan_config_cmd
=
{};
struct
iwl_wowlan_config_cmd
_v3
wowlan_config_cmd
=
{};
struct
iwl_wowlan_kek_kck_material_cmd
kek_kck_cmd
=
{};
struct
iwl_wowlan_kek_kck_material_cmd
kek_kck_cmd
=
{};
struct
iwl_wowlan_tkip_params_cmd
tkip_cmd
=
{};
struct
iwl_wowlan_tkip_params_cmd
tkip_cmd
=
{};
struct
iwl_d3_manager_config
d3_cfg_cmd_data
=
{
struct
iwl_d3_manager_config
d3_cfg_cmd_data
=
{
...
@@ -961,7 +842,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
...
@@ -961,7 +842,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
.
tkip
=
&
tkip_cmd
,
.
tkip
=
&
tkip_cmd
,
.
use_tkip
=
false
,
.
use_tkip
=
false
,
};
};
int
ret
,
i
;
int
ret
;
int
len
__maybe_unused
;
int
len
__maybe_unused
;
if
(
!
wowlan
)
{
if
(
!
wowlan
)
{
...
@@ -1002,49 +883,41 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
...
@@ -1002,49 +883,41 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
mvm_ap_sta
=
(
struct
iwl_mvm_sta
*
)
ap_sta
->
drv_priv
;
mvm_ap_sta
=
(
struct
iwl_mvm_sta
*
)
ap_sta
->
drv_priv
;
/* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */
/* TODO: wowlan_config_cmd.
common.
wowlan_ba_teardown_tids */
wowlan_config_cmd
.
is_11n_connection
=
ap_sta
->
ht_cap
.
ht_supported
;
wowlan_config_cmd
.
common
.
is_11n_connection
=
ap_sta
->
ht_cap
.
ht_supported
;
/* Query the last used seqno and set it */
/* Query the last used seqno and set it */
ret
=
iwl_mvm_get_last_nonqos_seq
(
mvm
,
vif
);
ret
=
iwl_mvm_get_last_nonqos_seq
(
mvm
,
vif
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
out_noreset
;
goto
out_noreset
;
wowlan_config_cmd
.
non_qos_seq
=
cpu_to_le16
(
ret
);
wowlan_config_cmd
.
common
.
non_qos_seq
=
cpu_to_le16
(
ret
);
/*
iwl_mvm_set_wowlan_qos_seq
(
mvm_ap_sta
,
&
wowlan_config_cmd
.
common
);
* For QoS counters, we store the one to use next, so subtract 0x10
* since the uCode will add 0x10 *before* using the value while we
* increment after using the value (i.e. store the next value to use).
*/
for
(
i
=
0
;
i
<
IWL_MAX_TID_COUNT
;
i
++
)
{
u16
seq
=
mvm_ap_sta
->
tid_data
[
i
].
seq_number
;
seq
-=
0x10
;
wowlan_config_cmd
.
qos_seq
[
i
]
=
cpu_to_le16
(
seq
);
}
if
(
wowlan
->
disconnect
)
if
(
wowlan
->
disconnect
)
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_BEACON_MISS
|
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_BEACON_MISS
|
IWL_WOWLAN_WAKEUP_LINK_CHANGE
);
IWL_WOWLAN_WAKEUP_LINK_CHANGE
);
if
(
wowlan
->
magic_pkt
)
if
(
wowlan
->
magic_pkt
)
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_MAGIC_PACKET
);
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_MAGIC_PACKET
);
if
(
wowlan
->
gtk_rekey_failure
)
if
(
wowlan
->
gtk_rekey_failure
)
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL
);
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL
);
if
(
wowlan
->
eap_identity_req
)
if
(
wowlan
->
eap_identity_req
)
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ
);
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ
);
if
(
wowlan
->
four_way_handshake
)
if
(
wowlan
->
four_way_handshake
)
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE
);
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE
);
if
(
wowlan
->
n_patterns
)
if
(
wowlan
->
n_patterns
)
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_PATTERN_MATCH
);
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_PATTERN_MATCH
);
if
(
wowlan
->
rfkill_release
)
if
(
wowlan
->
rfkill_release
)
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT
);
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT
);
if
(
wowlan
->
tcp
)
{
if
(
wowlan
->
tcp
)
{
...
@@ -1052,7 +925,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
...
@@ -1052,7 +925,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
* Set the "link change" (really "link lost") flag as well
* Set the "link change" (really "link lost") flag as well
* since that implies losing the TCP connection.
* since that implies losing the TCP connection.
*/
*/
wowlan_config_cmd
.
wakeup_filter
|=
wowlan_config_cmd
.
common
.
wakeup_filter
|=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS
|
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS
|
IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE
|
IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE
|
IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET
|
IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET
|
...
@@ -1150,9 +1023,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
...
@@ -1150,9 +1023,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
}
}
}
}
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
WOWLAN_CONFIGURATION
,
ret
=
iwl_mvm_send_wowlan_config_cmd
(
mvm
,
&
wowlan_config_cmd
);
CMD_SYNC
,
sizeof
(
wowlan_config_cmd
),
&
wowlan_config_cmd
);
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
...
@@ -1160,7 +1031,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
...
@@ -1160,7 +1031,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
ret
=
iwl_mvm_send_proto_offload
(
mvm
,
vif
);
ret
=
iwl_mvm_send_proto_offload
(
mvm
,
vif
,
false
,
CMD_SYNC
);
if
(
ret
)
if
(
ret
)
goto
out
;
goto
out
;
...
...
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
浏览文件 @
aa4a6250
...
@@ -312,6 +312,11 @@ static ssize_t iwl_dbgfs_reduced_txp_write(struct ieee80211_vif *vif,
...
@@ -312,6 +312,11 @@ static ssize_t iwl_dbgfs_reduced_txp_write(struct ieee80211_vif *vif,
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
mvmsta
=
iwl_mvm_sta_from_staid_protected
(
mvm
,
mvmvif
->
ap_sta_id
);
mvmsta
=
iwl_mvm_sta_from_staid_protected
(
mvm
,
mvmvif
->
ap_sta_id
);
if
(
IS_ERR_OR_NULL
(
mvmsta
))
{
mutex_unlock
(
&
mvm
->
mutex
);
return
-
ENOTCONN
;
}
mvmsta
->
bt_reduced_txpower_dbg
=
false
;
mvmsta
->
bt_reduced_txpower_dbg
=
false
;
ret
=
iwl_mvm_bt_coex_reduced_txp
(
mvm
,
mvmvif
->
ap_sta_id
,
ret
=
iwl_mvm_bt_coex_reduced_txp
(
mvm
,
mvmvif
->
ap_sta_id
,
reduced_tx_power
);
reduced_tx_power
);
...
...
drivers/net/wireless/iwlwifi/mvm/debugfs.c
浏览文件 @
aa4a6250
...
@@ -65,6 +65,7 @@
...
@@ -65,6 +65,7 @@
#include "iwl-io.h"
#include "iwl-io.h"
#include "iwl-prph.h"
#include "iwl-prph.h"
#include "debugfs.h"
#include "debugfs.h"
#include "fw-error-dump.h"
static
ssize_t
iwl_dbgfs_tx_flush_write
(
struct
iwl_mvm
*
mvm
,
char
*
buf
,
static
ssize_t
iwl_dbgfs_tx_flush_write
(
struct
iwl_mvm
*
mvm
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
size_t
count
,
loff_t
*
ppos
)
...
@@ -117,6 +118,51 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
...
@@ -117,6 +118,51 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
return
ret
;
return
ret
;
}
}
static
int
iwl_dbgfs_fw_error_dump_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
iwl_mvm
*
mvm
=
inode
->
i_private
;
int
ret
;
if
(
!
mvm
)
return
-
EINVAL
;
mutex_lock
(
&
mvm
->
mutex
);
if
(
!
mvm
->
fw_error_dump
)
{
ret
=
-
ENODATA
;
goto
out
;
}
file
->
private_data
=
mvm
->
fw_error_dump
;
mvm
->
fw_error_dump
=
NULL
;
kfree
(
mvm
->
fw_error_sram
);
mvm
->
fw_error_sram
=
NULL
;
mvm
->
fw_error_sram_len
=
0
;
ret
=
0
;
out:
mutex_unlock
(
&
mvm
->
mutex
);
return
ret
;
}
static
ssize_t
iwl_dbgfs_fw_error_dump_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_fw_error_dump_file
*
dump_file
=
file
->
private_data
;
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
dump_file
,
le32_to_cpu
(
dump_file
->
file_len
));
}
static
int
iwl_dbgfs_fw_error_dump_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
vfree
(
file
->
private_data
);
return
0
;
}
static
ssize_t
iwl_dbgfs_sram_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
static
ssize_t
iwl_dbgfs_sram_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
size_t
count
,
loff_t
*
ppos
)
{
{
...
@@ -350,6 +396,9 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
...
@@ -350,6 +396,9 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
le32_to_cpu
(
notif
->
secondary_ch_lut
));
le32_to_cpu
(
notif
->
secondary_ch_lut
));
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_activity_grading = %d
\n
"
,
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"bt_activity_grading = %d
\n
"
,
le32_to_cpu
(
notif
->
bt_activity_grading
));
le32_to_cpu
(
notif
->
bt_activity_grading
));
pos
+=
scnprintf
(
buf
+
pos
,
bufsz
-
pos
,
"antenna isolation = %d CORUN LUT index = %d
\n
"
,
mvm
->
last_ant_isol
,
mvm
->
last_corun_lut
);
mutex_unlock
(
&
mvm
->
mutex
);
mutex_unlock
(
&
mvm
->
mutex
);
...
@@ -392,6 +441,22 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
...
@@ -392,6 +441,22 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
}
}
static
ssize_t
iwl_dbgfs_bt_tx_prio_write
(
struct
iwl_mvm
*
mvm
,
char
*
buf
,
size_t
count
,
loff_t
*
ppos
)
{
u32
bt_tx_prio
;
if
(
sscanf
(
buf
,
"%u"
,
&
bt_tx_prio
)
!=
1
)
return
-
EINVAL
;
if
(
bt_tx_prio
>
4
)
return
-
EINVAL
;
mvm
->
bt_tx_prio
=
bt_tx_prio
;
return
count
;
}
#define PRINT_STATS_LE32(_str, _val) \
#define PRINT_STATS_LE32(_str, _val) \
pos += scnprintf(buf + pos, bufsz - pos, \
pos += scnprintf(buf + pos, bufsz - pos, \
fmt_table, _str, \
fmt_table, _str, \
...
@@ -536,56 +601,60 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
...
@@ -536,56 +601,60 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
loff_t
*
ppos
,
loff_t
*
ppos
,
struct
iwl_mvm_frame_stats
*
stats
)
struct
iwl_mvm_frame_stats
*
stats
)
{
{
char
*
buff
;
char
*
buff
,
*
pos
,
*
endpos
;
int
pos
=
0
,
idx
,
i
;
int
idx
,
i
;
int
ret
;
int
ret
;
size_t
bufsz
=
1024
;
s
tatic
const
s
ize_t
bufsz
=
1024
;
buff
=
kmalloc
(
bufsz
,
GFP_KERNEL
);
buff
=
kmalloc
(
bufsz
,
GFP_KERNEL
);
if
(
!
buff
)
if
(
!
buff
)
return
-
ENOMEM
;
return
-
ENOMEM
;
spin_lock_bh
(
&
mvm
->
drv_stats_lock
);
spin_lock_bh
(
&
mvm
->
drv_stats_lock
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
pos
=
buff
;
endpos
=
pos
+
bufsz
;
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"Legacy/HT/VHT
\t
:
\t
%d/%d/%d
\n
"
,
"Legacy/HT/VHT
\t
:
\t
%d/%d/%d
\n
"
,
stats
->
legacy_frames
,
stats
->
legacy_frames
,
stats
->
ht_frames
,
stats
->
ht_frames
,
stats
->
vht_frames
);
stats
->
vht_frames
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"20/40/80
\t
:
\t
%d/%d/%d
\n
"
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"20/40/80
\t
:
\t
%d/%d/%d
\n
"
,
stats
->
bw_20_frames
,
stats
->
bw_20_frames
,
stats
->
bw_40_frames
,
stats
->
bw_40_frames
,
stats
->
bw_80_frames
);
stats
->
bw_80_frames
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"NGI/SGI
\t\t
:
\t
%d/%d
\n
"
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"NGI/SGI
\t\t
:
\t
%d/%d
\n
"
,
stats
->
ngi_frames
,
stats
->
ngi_frames
,
stats
->
sgi_frames
);
stats
->
sgi_frames
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"SISO/MIMO2
\t
:
\t
%d/%d
\n
"
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"SISO/MIMO2
\t
:
\t
%d/%d
\n
"
,
stats
->
siso_frames
,
stats
->
siso_frames
,
stats
->
mimo2_frames
);
stats
->
mimo2_frames
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"FAIL/SCSS
\t
:
\t
%d/%d
\n
"
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"FAIL/SCSS
\t
:
\t
%d/%d
\n
"
,
stats
->
fail_frames
,
stats
->
fail_frames
,
stats
->
success_frames
);
stats
->
success_frames
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"MPDUs agg
\t
:
\t
%d
\n
"
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"MPDUs agg
\t
:
\t
%d
\n
"
,
stats
->
agg_frames
);
stats
->
agg_frames
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"A-MPDUs
\t\t
:
\t
%d
\n
"
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"A-MPDUs
\t\t
:
\t
%d
\n
"
,
stats
->
ampdu_count
);
stats
->
ampdu_count
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"Avg MPDUs/A-MPDU:
\t
%d
\n
"
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"Avg MPDUs/A-MPDU:
\t
%d
\n
"
,
stats
->
ampdu_count
>
0
?
stats
->
ampdu_count
>
0
?
(
stats
->
agg_frames
/
stats
->
ampdu_count
)
:
0
);
(
stats
->
agg_frames
/
stats
->
ampdu_count
)
:
0
);
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"Last Rates
\n
"
);
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"Last Rates
\n
"
);
idx
=
stats
->
last_frame_idx
-
1
;
idx
=
stats
->
last_frame_idx
-
1
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
stats
->
last_rates
);
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
stats
->
last_rates
);
i
++
)
{
idx
=
(
idx
+
1
)
%
ARRAY_SIZE
(
stats
->
last_rates
);
idx
=
(
idx
+
1
)
%
ARRAY_SIZE
(
stats
->
last_rates
);
if
(
stats
->
last_rates
[
idx
]
==
0
)
if
(
stats
->
last_rates
[
idx
]
==
0
)
continue
;
continue
;
pos
+=
scnprintf
(
buff
+
pos
,
bufsz
-
pos
,
"Rate[%d]: "
,
pos
+=
scnprintf
(
pos
,
endpos
-
pos
,
"Rate[%d]: "
,
(
int
)(
ARRAY_SIZE
(
stats
->
last_rates
)
-
i
));
(
int
)(
ARRAY_SIZE
(
stats
->
last_rates
)
-
i
));
pos
+=
rs_pretty_print_rate
(
buff
+
pos
,
stats
->
last_rates
[
idx
]);
pos
+=
rs_pretty_print_rate
(
pos
,
stats
->
last_rates
[
idx
]);
}
}
spin_unlock_bh
(
&
mvm
->
drv_stats_lock
);
spin_unlock_bh
(
&
mvm
->
drv_stats_lock
);
ret
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buff
,
pos
);
ret
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buff
,
pos
-
buff
);
kfree
(
buff
);
kfree
(
buff
);
return
ret
;
return
ret
;
...
@@ -1032,9 +1101,16 @@ MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
...
@@ -1032,9 +1101,16 @@ MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
MVM_DEBUGFS_READ_FILE_OPS
(
drv_rx_stats
);
MVM_DEBUGFS_READ_FILE_OPS
(
drv_rx_stats
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_restart
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_restart
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_nmi
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
fw_nmi
,
10
);
MVM_DEBUGFS_WRITE_FILE_OPS
(
bt_tx_prio
,
10
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
scan_ant_rxchain
,
8
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
scan_ant_rxchain
,
8
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
d0i3_refs
,
8
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
d0i3_refs
,
8
);
static
const
struct
file_operations
iwl_dbgfs_fw_error_dump_ops
=
{
.
open
=
iwl_dbgfs_fw_error_dump_open
,
.
read
=
iwl_dbgfs_fw_error_dump_read
,
.
release
=
iwl_dbgfs_fw_error_dump_release
,
};
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
bcast_filters
,
256
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
bcast_filters
,
256
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
bcast_filters_macs
,
256
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
bcast_filters_macs
,
256
);
...
@@ -1049,12 +1125,15 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
...
@@ -1049,12 +1125,15 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
struct
dentry
*
bcast_dir
__maybe_unused
;
struct
dentry
*
bcast_dir
__maybe_unused
;
char
buf
[
100
];
char
buf
[
100
];
spin_lock_init
(
&
mvm
->
drv_stats_lock
);
mvm
->
debugfs_dir
=
dbgfs_dir
;
mvm
->
debugfs_dir
=
dbgfs_dir
;
MVM_DEBUGFS_ADD_FILE
(
tx_flush
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
tx_flush
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
sta_drain
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
sta_drain
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
sram
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
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
(
stations
,
dbgfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_error_dump
,
dbgfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_notif
,
dbgfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_notif
,
dbgfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_cmd
,
dbgfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_cmd
,
dbgfs_dir
,
S_IRUSR
);
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
)
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD
)
...
@@ -1064,6 +1143,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
...
@@ -1064,6 +1143,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE
(
drv_rx_stats
,
mvm
->
debugfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
drv_rx_stats
,
mvm
->
debugfs_dir
,
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_restart
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_restart
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_nmi
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
fw_nmi
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
bt_tx_prio
,
mvm
->
debugfs_dir
,
S_IWUSR
);
MVM_DEBUGFS_ADD_FILE
(
scan_ant_rxchain
,
mvm
->
debugfs_dir
,
MVM_DEBUGFS_ADD_FILE
(
scan_ant_rxchain
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
S_IWUSR
|
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
prph_reg
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
prph_reg
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-
bt-
coex.h
→
drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
浏览文件 @
aa4a6250
...
@@ -77,6 +77,8 @@
...
@@ -77,6 +77,8 @@
* @BT_COEX_3W:
* @BT_COEX_3W:
* @BT_COEX_NW:
* @BT_COEX_NW:
* @BT_COEX_SYNC2SCO:
* @BT_COEX_SYNC2SCO:
* @BT_COEX_CORUNNING:
* @BT_COEX_MPLUT:
*
*
* The COEX_MODE must be set for each command. Even if it is not changed.
* The COEX_MODE must be set for each command. Even if it is not changed.
*/
*/
...
@@ -88,6 +90,8 @@ enum iwl_bt_coex_flags {
...
@@ -88,6 +90,8 @@ enum iwl_bt_coex_flags {
BT_COEX_3W
=
0x2
<<
BT_COEX_MODE_POS
,
BT_COEX_3W
=
0x2
<<
BT_COEX_MODE_POS
,
BT_COEX_NW
=
0x3
<<
BT_COEX_MODE_POS
,
BT_COEX_NW
=
0x3
<<
BT_COEX_MODE_POS
,
BT_COEX_SYNC2SCO
=
BIT
(
7
),
BT_COEX_SYNC2SCO
=
BIT
(
7
),
BT_COEX_CORUNNING
=
BIT
(
8
),
BT_COEX_MPLUT
=
BIT
(
9
),
};
};
/*
/*
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
浏览文件 @
aa4a6250
...
@@ -239,7 +239,7 @@ enum iwl_wowlan_wakeup_filters {
...
@@ -239,7 +239,7 @@ enum iwl_wowlan_wakeup_filters {
IWL_WOWLAN_WAKEUP_BCN_FILTERING
=
BIT
(
16
),
IWL_WOWLAN_WAKEUP_BCN_FILTERING
=
BIT
(
16
),
};
/* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
};
/* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
struct
iwl_wowlan_config_cmd
{
struct
iwl_wowlan_config_cmd
_v2
{
__le32
wakeup_filter
;
__le32
wakeup_filter
;
__le16
non_qos_seq
;
__le16
non_qos_seq
;
__le16
qos_seq
[
8
];
__le16
qos_seq
[
8
];
...
@@ -247,6 +247,12 @@ struct iwl_wowlan_config_cmd {
...
@@ -247,6 +247,12 @@ struct iwl_wowlan_config_cmd {
u8
is_11n_connection
;
u8
is_11n_connection
;
}
__packed
;
/* WOWLAN_CONFIG_API_S_VER_2 */
}
__packed
;
/* WOWLAN_CONFIG_API_S_VER_2 */
struct
iwl_wowlan_config_cmd_v3
{
struct
iwl_wowlan_config_cmd_v2
common
;
u8
offloading_tid
;
u8
reserved
[
3
];
}
__packed
;
/* WOWLAN_CONFIG_API_S_VER_3 */
/*
/*
* WOWLAN_TSC_RSC_PARAMS
* WOWLAN_TSC_RSC_PARAMS
*/
*/
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
浏览文件 @
aa4a6250
...
@@ -76,6 +76,8 @@
...
@@ -76,6 +76,8 @@
* @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence
* @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence
* @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence
* @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence
* @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC)
* @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC)
* @TX_CMD_FLG_BT_PRIO_POS: the position of the BT priority (bit 11 is ignored
* on old firmwares).
* @TX_CMD_FLG_BT_DIS: disable BT priority for this frame
* @TX_CMD_FLG_BT_DIS: disable BT priority for this frame
* @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control.
* @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control.
* Should be set for mgmt, non-QOS data, mcast, bcast and in scan command
* Should be set for mgmt, non-QOS data, mcast, bcast and in scan command
...
@@ -107,6 +109,7 @@ enum iwl_tx_flags {
...
@@ -107,6 +109,7 @@ enum iwl_tx_flags {
TX_CMD_FLG_VHT_NDPA
=
BIT
(
8
),
TX_CMD_FLG_VHT_NDPA
=
BIT
(
8
),
TX_CMD_FLG_HT_NDPA
=
BIT
(
9
),
TX_CMD_FLG_HT_NDPA
=
BIT
(
9
),
TX_CMD_FLG_CSI_FDBK2HOST
=
BIT
(
10
),
TX_CMD_FLG_CSI_FDBK2HOST
=
BIT
(
10
),
TX_CMD_FLG_BT_PRIO_POS
=
11
,
TX_CMD_FLG_BT_DIS
=
BIT
(
12
),
TX_CMD_FLG_BT_DIS
=
BIT
(
12
),
TX_CMD_FLG_SEQ_CTL
=
BIT
(
13
),
TX_CMD_FLG_SEQ_CTL
=
BIT
(
13
),
TX_CMD_FLG_MORE_FRAG
=
BIT
(
14
),
TX_CMD_FLG_MORE_FRAG
=
BIT
(
14
),
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api.h
浏览文件 @
aa4a6250
...
@@ -70,7 +70,7 @@
...
@@ -70,7 +70,7 @@
#include "fw-api-mac.h"
#include "fw-api-mac.h"
#include "fw-api-power.h"
#include "fw-api-power.h"
#include "fw-api-d3.h"
#include "fw-api-d3.h"
#include "fw-api-
bt-
coex.h"
#include "fw-api-coex.h"
/* maximal number of Tx queues in any platform */
/* maximal number of Tx queues in any platform */
#define IWL_MVM_MAX_QUEUES 20
#define IWL_MVM_MAX_QUEUES 20
...
@@ -95,6 +95,7 @@ enum {
...
@@ -95,6 +95,7 @@ enum {
/* PHY context commands */
/* PHY context commands */
PHY_CONTEXT_CMD
=
0x8
,
PHY_CONTEXT_CMD
=
0x8
,
DBG_CFG
=
0x9
,
DBG_CFG
=
0x9
,
ANTENNA_COUPLING_NOTIFICATION
=
0xa
,
/* station table */
/* station table */
ADD_STA_KEY
=
0x17
,
ADD_STA_KEY
=
0x17
,
...
...
drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
0 → 100644
浏览文件 @
aa4a6250
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2014 Intel 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) 2014 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 __fw_error_dump_h__
#define __fw_error_dump_h__
#include <linux/types.h>
#define IWL_FW_ERROR_DUMP_BARKER 0x14789632
/**
* enum iwl_fw_error_dump_type - types of data in the dump file
* @IWL_FW_ERROR_DUMP_SRAM:
* @IWL_FW_ERROR_DUMP_REG:
*/
enum
iwl_fw_error_dump_type
{
IWL_FW_ERROR_DUMP_SRAM
=
0
,
IWL_FW_ERROR_DUMP_REG
=
1
,
IWL_FW_ERROR_DUMP_MAX
,
};
/**
* struct iwl_fw_error_dump_data - data for one type
* @type: %enum iwl_fw_error_dump_type
* @len: the length starting from %data - must be a multiplier of 4.
* @data: the data itself padded to be a multiplier of 4.
*/
struct
iwl_fw_error_dump_data
{
__le32
type
;
__le32
len
;
__u8
data
[];
}
__packed
__aligned
(
4
);
/**
* struct iwl_fw_error_dump_file - the layout of the header of the file
* @barker: must be %IWL_FW_ERROR_DUMP_BARKER
* @file_len: the length of all the file starting from %barker
* @data: array of %struct iwl_fw_error_dump_data
*/
struct
iwl_fw_error_dump_file
{
__le32
barker
;
__le32
file_len
;
u8
data
[
0
];
}
__packed
__aligned
(
4
);
#endif
/* __fw_error_dump_h__ */
drivers/net/wireless/iwlwifi/mvm/led.c
浏览文件 @
aa4a6250
...
@@ -94,6 +94,8 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
...
@@ -94,6 +94,8 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
int
ret
;
int
ret
;
switch
(
mode
)
{
switch
(
mode
)
{
case
IWL_LED_BLINK
:
IWL_ERR
(
mvm
,
"Blink led mode not supported, used default
\n
"
);
case
IWL_LED_DEFAULT
:
case
IWL_LED_DEFAULT
:
case
IWL_LED_RF_STATE
:
case
IWL_LED_RF_STATE
:
mode
=
IWL_LED_RF_STATE
;
mode
=
IWL_LED_RF_STATE
;
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
浏览文件 @
aa4a6250
...
@@ -205,7 +205,7 @@ static const struct iwl_fw_bcast_filter iwl_mvm_default_bcast_filters[] = {
...
@@ -205,7 +205,7 @@ static const struct iwl_fw_bcast_filter iwl_mvm_default_bcast_filters[] = {
void
iwl_mvm_ref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
)
void
iwl_mvm_ref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
)
{
{
if
(
!
mvm
->
trans
->
cfg
->
d0i3
)
if
(
!
iwl_mvm_is_d0i3_supported
(
mvm
)
)
return
;
return
;
IWL_DEBUG_RPM
(
mvm
,
"Take mvm reference - type %d
\n
"
,
ref_type
);
IWL_DEBUG_RPM
(
mvm
,
"Take mvm reference - type %d
\n
"
,
ref_type
);
...
@@ -215,7 +215,7 @@ void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
...
@@ -215,7 +215,7 @@ void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
void
iwl_mvm_unref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
)
void
iwl_mvm_unref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
)
{
{
if
(
!
mvm
->
trans
->
cfg
->
d0i3
)
if
(
!
iwl_mvm_is_d0i3_supported
(
mvm
)
)
return
;
return
;
IWL_DEBUG_RPM
(
mvm
,
"Leave mvm reference - type %d
\n
"
,
ref_type
);
IWL_DEBUG_RPM
(
mvm
,
"Leave mvm reference - type %d
\n
"
,
ref_type
);
...
@@ -228,7 +228,7 @@ iwl_mvm_unref_all_except(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref)
...
@@ -228,7 +228,7 @@ iwl_mvm_unref_all_except(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref)
{
{
int
i
;
int
i
;
if
(
!
mvm
->
trans
->
cfg
->
d0i3
)
if
(
!
iwl_mvm_is_d0i3_supported
(
mvm
)
)
return
;
return
;
for_each_set_bit
(
i
,
mvm
->
ref_bitmap
,
IWL_MVM_REF_COUNT
)
{
for_each_set_bit
(
i
,
mvm
->
ref_bitmap
,
IWL_MVM_REF_COUNT
)
{
...
@@ -295,7 +295,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
...
@@ -295,7 +295,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
!
iwlwifi_mod_params
.
sw_crypto
)
!
iwlwifi_mod_params
.
sw_crypto
)
hw
->
flags
|=
IEEE80211_HW_MFP_CAPABLE
;
hw
->
flags
|=
IEEE80211_HW_MFP_CAPABLE
;
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT
)
{
if
(
0
&&
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT
)
{
hw
->
flags
|=
IEEE80211_HW_SUPPORTS_UAPSD
;
hw
->
flags
|=
IEEE80211_HW_SUPPORTS_UAPSD
;
hw
->
uapsd_queues
=
IWL_UAPSD_AC_INFO
;
hw
->
uapsd_queues
=
IWL_UAPSD_AC_INFO
;
hw
->
uapsd_max_sp_len
=
IWL_UAPSD_MAX_SP
;
hw
->
uapsd_max_sp_len
=
IWL_UAPSD_MAX_SP
;
...
@@ -365,7 +365,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
...
@@ -365,7 +365,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
else
else
hw
->
wiphy
->
flags
&=
~
WIPHY_FLAG_PS_ON_BY_DEFAULT
;
hw
->
wiphy
->
flags
&=
~
WIPHY_FLAG_PS_ON_BY_DEFAULT
;
if
(
0
&&
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_SCHED_SCAN
)
{
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_SCHED_SCAN
)
{
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
hw
->
wiphy
->
max_sched_scan_ssids
=
PROBE_OPTION_MAX
;
hw
->
wiphy
->
max_sched_scan_ssids
=
PROBE_OPTION_MAX
;
hw
->
wiphy
->
max_match_sets
=
IWL_SCAN_MAX_PROFILES
;
hw
->
wiphy
->
max_match_sets
=
IWL_SCAN_MAX_PROFILES
;
...
@@ -375,8 +375,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
...
@@ -375,8 +375,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
}
}
hw
->
wiphy
->
features
|=
NL80211_FEATURE_P2P_GO_CTWIN
|
hw
->
wiphy
->
features
|=
NL80211_FEATURE_P2P_GO_CTWIN
|
NL80211_FEATURE_P2P_GO_OPPPS
|
NL80211_FEATURE_P2P_GO_OPPPS
;
NL80211_FEATURE_LOW_PRIORITY_SCAN
;
mvm
->
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
;
mvm
->
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
;
...
@@ -424,6 +423,47 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
...
@@ -424,6 +423,47 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
return
ret
;
return
ret
;
}
}
static
bool
iwl_mvm_defer_tx
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
,
struct
sk_buff
*
skb
)
{
struct
iwl_mvm_sta
*
mvmsta
;
bool
defer
=
false
;
/*
* double check the IN_D0I3 flag both before and after
* taking the spinlock, in order to prevent taking
* the spinlock when not needed.
*/
if
(
likely
(
!
test_bit
(
IWL_MVM_STATUS_IN_D0I3
,
&
mvm
->
status
)))
return
false
;
spin_lock
(
&
mvm
->
d0i3_tx_lock
);
/*
* testing the flag again ensures the skb dequeue
* loop (on d0i3 exit) hasn't run yet.
*/
if
(
!
test_bit
(
IWL_MVM_STATUS_IN_D0I3
,
&
mvm
->
status
))
goto
out
;
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
if
(
mvmsta
->
sta_id
==
IWL_MVM_STATION_COUNT
||
mvmsta
->
sta_id
!=
mvm
->
d0i3_ap_sta_id
)
goto
out
;
__skb_queue_tail
(
&
mvm
->
d0i3_tx
,
skb
);
ieee80211_stop_queues
(
mvm
->
hw
);
/* trigger wakeup */
iwl_mvm_ref
(
mvm
,
IWL_MVM_REF_TX
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_TX
);
defer
=
true
;
out:
spin_unlock
(
&
mvm
->
d0i3_tx_lock
);
return
defer
;
}
static
void
iwl_mvm_mac_tx
(
struct
ieee80211_hw
*
hw
,
static
void
iwl_mvm_mac_tx
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_tx_control
*
control
,
struct
ieee80211_tx_control
*
control
,
struct
sk_buff
*
skb
)
struct
sk_buff
*
skb
)
...
@@ -451,6 +491,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
...
@@ -451,6 +491,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
sta
=
NULL
;
sta
=
NULL
;
if
(
sta
)
{
if
(
sta
)
{
if
(
iwl_mvm_defer_tx
(
mvm
,
sta
,
skb
))
return
;
if
(
iwl_mvm_tx_skb
(
mvm
,
skb
,
sta
))
if
(
iwl_mvm_tx_skb
(
mvm
,
skb
,
sta
))
goto
drop
;
goto
drop
;
return
;
return
;
...
@@ -489,6 +531,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
...
@@ -489,6 +531,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
{
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
int
ret
;
int
ret
;
bool
tx_agg_ref
=
false
;
IWL_DEBUG_HT
(
mvm
,
"A-MPDU action on addr %pM tid %d: action %d
\n
"
,
IWL_DEBUG_HT
(
mvm
,
"A-MPDU action on addr %pM tid %d: action %d
\n
"
,
sta
->
addr
,
tid
,
action
);
sta
->
addr
,
tid
,
action
);
...
@@ -496,6 +539,23 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
...
@@ -496,6 +539,23 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
if
(
!
(
mvm
->
nvm_data
->
sku_cap_11n_enable
))
if
(
!
(
mvm
->
nvm_data
->
sku_cap_11n_enable
))
return
-
EACCES
;
return
-
EACCES
;
/* return from D0i3 before starting a new Tx aggregation */
if
(
action
==
IEEE80211_AMPDU_TX_START
)
{
iwl_mvm_ref
(
mvm
,
IWL_MVM_REF_TX_AGG
);
tx_agg_ref
=
true
;
/*
* wait synchronously until D0i3 exit to get the correct
* sequence number for the tid
*/
if
(
!
wait_event_timeout
(
mvm
->
d0i3_exit_waitq
,
!
test_bit
(
IWL_MVM_STATUS_IN_D0I3
,
&
mvm
->
status
),
HZ
))
{
WARN_ON_ONCE
(
1
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_TX_AGG
);
return
-
EIO
;
}
}
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
switch
(
action
)
{
switch
(
action
)
{
...
@@ -533,6 +593,13 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
...
@@ -533,6 +593,13 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
}
}
mutex_unlock
(
&
mvm
->
mutex
);
mutex_unlock
(
&
mvm
->
mutex
);
/*
* If the tid is marked as started, we won't use it for offloaded
* traffic on the next D0i3 entry. It's safe to unref.
*/
if
(
tx_agg_ref
)
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_TX_AGG
);
return
ret
;
return
ret
;
}
}
...
@@ -557,6 +624,15 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
...
@@ -557,6 +624,15 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
static
void
iwl_mvm_restart_cleanup
(
struct
iwl_mvm
*
mvm
)
static
void
iwl_mvm_restart_cleanup
(
struct
iwl_mvm
*
mvm
)
{
{
#ifdef CONFIG_IWLWIFI_DEBUGFS
static
char
*
env
[]
=
{
"DRIVER=iwlwifi"
,
"EVENT=error_dump"
,
NULL
};
iwl_mvm_fw_error_dump
(
mvm
);
/* notify the userspace about the error we had */
kobject_uevent_env
(
&
mvm
->
hw
->
wiphy
->
dev
.
kobj
,
KOBJ_CHANGE
,
env
);
#endif
iwl_trans_stop_device
(
mvm
->
trans
);
iwl_trans_stop_device
(
mvm
->
trans
);
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
...
@@ -610,6 +686,7 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
...
@@ -610,6 +686,7 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
clear_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
);
clear_bit
(
IWL_MVM_STATUS_IN_HW_RESTART
,
&
mvm
->
status
);
iwl_mvm_d0i3_enable_tx
(
mvm
,
NULL
);
ret
=
iwl_mvm_update_quotas
(
mvm
,
NULL
);
ret
=
iwl_mvm_update_quotas
(
mvm
,
NULL
);
if
(
ret
)
if
(
ret
)
IWL_ERR
(
mvm
,
"Failed to update quotas after restart (%d)
\n
"
,
IWL_ERR
(
mvm
,
"Failed to update quotas after restart (%d)
\n
"
,
...
@@ -1255,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
...
@@ -1255,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
*/
*/
iwl_mvm_remove_time_event
(
mvm
,
mvmvif
,
iwl_mvm_remove_time_event
(
mvm
,
mvmvif
,
&
mvmvif
->
time_event_data
);
&
mvmvif
->
time_event_data
);
WARN_ON
(
iwl_mvm_enable_beacon_filter
(
mvm
,
vif
,
CMD_SYNC
));
}
else
if
(
changes
&
(
BSS_CHANGED_PS
|
BSS_CHANGED_P2P_PS
|
}
else
if
(
changes
&
(
BSS_CHANGED_PS
|
BSS_CHANGED_P2P_PS
|
BSS_CHANGED_QOS
))
{
BSS_CHANGED_QOS
))
{
ret
=
iwl_mvm_power_update_mac
(
mvm
,
vif
);
ret
=
iwl_mvm_power_update_mac
(
mvm
,
vif
);
...
@@ -1437,8 +1515,6 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
...
@@ -1437,8 +1515,6 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
struct
cfg80211_scan_request
*
req
)
struct
cfg80211_scan_request
*
req
)
{
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_notification_wait
wait_scan_done
;
static
const
u8
scan_done_notif
[]
=
{
SCAN_OFFLOAD_COMPLETE
,
};
int
ret
;
int
ret
;
if
(
req
->
n_channels
==
0
||
req
->
n_channels
>
MAX_NUM_SCAN_CHANNELS
)
if
(
req
->
n_channels
==
0
||
req
->
n_channels
>
MAX_NUM_SCAN_CHANNELS
)
...
@@ -1448,22 +1524,11 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
...
@@ -1448,22 +1524,11 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
switch
(
mvm
->
scan_status
)
{
switch
(
mvm
->
scan_status
)
{
case
IWL_MVM_SCAN_SCHED
:
case
IWL_MVM_SCAN_SCHED
:
iwl_init_notification_wait
(
&
mvm
->
notif_wait
,
&
wait_scan_done
,
ret
=
iwl_mvm_sched_scan_stop
(
mvm
);
scan_done_notif
,
ARRAY_SIZE
(
scan_done_notif
),
NULL
,
NULL
);
iwl_mvm_sched_scan_stop
(
mvm
);
ret
=
iwl_wait_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_done
,
HZ
);
if
(
ret
)
{
if
(
ret
)
{
ret
=
-
EBUSY
;
ret
=
-
EBUSY
;
goto
out
;
goto
out
;
}
}
/* iwl_mvm_rx_scan_offload_complete_notif() will be called
* soon but will not reset the scan status as it won't be
* IWL_MVM_SCAN_SCHED any more since we queue the next scan
* immediately (below)
*/
break
;
break
;
case
IWL_MVM_SCAN_NONE
:
case
IWL_MVM_SCAN_NONE
:
break
;
break
;
...
@@ -1479,7 +1544,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
...
@@ -1479,7 +1544,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_SCAN
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_SCAN
);
out:
out:
mutex_unlock
(
&
mvm
->
mutex
);
mutex_unlock
(
&
mvm
->
mutex
);
/* make sure to flush the Rx handler before the next scan arrives */
iwl_mvm_wait_for_async_handlers
(
mvm
);
return
ret
;
return
ret
;
}
}
...
@@ -1641,7 +1707,9 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
...
@@ -1641,7 +1707,9 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
}
else
if
(
old_state
==
IEEE80211_STA_ASSOC
&&
}
else
if
(
old_state
==
IEEE80211_STA_ASSOC
&&
new_state
==
IEEE80211_STA_AUTHORIZED
)
{
new_state
==
IEEE80211_STA_AUTHORIZED
)
{
/* enable beacon filtering */
/* enable beacon filtering */
WARN_ON
(
iwl_mvm_enable_beacon_filter
(
mvm
,
vif
,
CMD_SYNC
));
if
(
vif
->
bss_conf
.
dtim_period
)
WARN_ON
(
iwl_mvm_enable_beacon_filter
(
mvm
,
vif
,
CMD_SYNC
));
ret
=
0
;
ret
=
0
;
}
else
if
(
old_state
==
IEEE80211_STA_AUTHORIZED
&&
}
else
if
(
old_state
==
IEEE80211_STA_AUTHORIZED
&&
new_state
==
IEEE80211_STA_ASSOC
)
{
new_state
==
IEEE80211_STA_ASSOC
)
{
...
@@ -1738,9 +1806,26 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
...
@@ -1738,9 +1806,26 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
if
(
mvm
->
scan_status
!=
IWL_MVM_SCAN_NONE
)
{
switch
(
mvm
->
scan_status
)
{
IWL_DEBUG_SCAN
(
mvm
,
case
IWL_MVM_SCAN_OS
:
"SCHED SCAN request during internal scan - abort
\n
"
);
IWL_DEBUG_SCAN
(
mvm
,
"Stopping previous scan for sched_scan
\n
"
);
ret
=
iwl_mvm_cancel_scan
(
mvm
);
if
(
ret
)
{
ret
=
-
EBUSY
;
goto
out
;
}
/*
* iwl_mvm_rx_scan_complete() will be called soon but will
* not reset the scan status as it won't be IWL_MVM_SCAN_OS
* any more since we queue the next scan immediately (below).
* We make sure it is called before the next scan starts by
* flushing the async-handlers work.
*/
break
;
case
IWL_MVM_SCAN_NONE
:
break
;
default:
ret
=
-
EBUSY
;
ret
=
-
EBUSY
;
goto
out
;
goto
out
;
}
}
...
@@ -1762,6 +1847,8 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
...
@@ -1762,6 +1847,8 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
out:
out:
mutex_unlock
(
&
mvm
->
mutex
);
mutex_unlock
(
&
mvm
->
mutex
);
/* make sure to flush the Rx handler before the next scan arrives */
iwl_mvm_wait_for_async_handlers
(
mvm
);
return
ret
;
return
ret
;
}
}
...
@@ -1769,12 +1856,14 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
...
@@ -1769,12 +1856,14 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
struct
ieee80211_vif
*
vif
)
struct
ieee80211_vif
*
vif
)
{
{
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
struct
iwl_mvm
*
mvm
=
IWL_MAC80211_GET_MVM
(
hw
);
int
ret
;
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
iwl_mvm_sched_scan_stop
(
mvm
);
ret
=
iwl_mvm_sched_scan_stop
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
mutex_unlock
(
&
mvm
->
mutex
);
iwl_mvm_wait_for_async_handlers
(
mvm
);
return
0
;
return
ret
;
}
}
static
int
iwl_mvm_mac_set_key
(
struct
ieee80211_hw
*
hw
,
static
int
iwl_mvm_mac_set_key
(
struct
ieee80211_hw
*
hw
,
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
浏览文件 @
aa4a6250
...
@@ -230,6 +230,8 @@ enum iwl_mvm_ref_type {
...
@@ -230,6 +230,8 @@ enum iwl_mvm_ref_type {
IWL_MVM_REF_P2P_CLIENT
,
IWL_MVM_REF_P2P_CLIENT
,
IWL_MVM_REF_AP_IBSS
,
IWL_MVM_REF_AP_IBSS
,
IWL_MVM_REF_USER
,
IWL_MVM_REF_USER
,
IWL_MVM_REF_TX
,
IWL_MVM_REF_TX_AGG
,
IWL_MVM_REF_COUNT
,
IWL_MVM_REF_COUNT
,
};
};
...
@@ -317,13 +319,13 @@ struct iwl_mvm_vif {
...
@@ -317,13 +319,13 @@ struct iwl_mvm_vif {
bool
seqno_valid
;
bool
seqno_valid
;
u16
seqno
;
u16
seqno
;
#endif
#if IS_ENABLED(CONFIG_IPV6)
#if IS_ENABLED(CONFIG_IPV6)
/* IPv6 addresses for WoWLAN */
/* IPv6 addresses for WoWLAN */
struct
in6_addr
target_ipv6_addrs
[
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX
];
struct
in6_addr
target_ipv6_addrs
[
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX
];
int
num_target_ipv6_addrs
;
int
num_target_ipv6_addrs
;
#endif
#endif
#endif
#ifdef CONFIG_IWLWIFI_DEBUGFS
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct
iwl_mvm
*
mvm
;
struct
iwl_mvm
*
mvm
;
...
@@ -346,6 +348,8 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
...
@@ -346,6 +348,8 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
return
(
void
*
)
vif
->
drv_priv
;
return
(
void
*
)
vif
->
drv_priv
;
}
}
extern
const
u8
tid_to_mac80211_ac
[];
enum
iwl_scan_status
{
enum
iwl_scan_status
{
IWL_MVM_SCAN_NONE
,
IWL_MVM_SCAN_NONE
,
IWL_MVM_SCAN_OS
,
IWL_MVM_SCAN_OS
,
...
@@ -571,6 +575,9 @@ struct iwl_mvm {
...
@@ -571,6 +575,9 @@ struct iwl_mvm {
/* -1 for always, 0 for never, >0 for that many times */
/* -1 for always, 0 for never, >0 for that many times */
s8
restart_fw
;
s8
restart_fw
;
void
*
fw_error_dump
;
void
*
fw_error_sram
;
u32
fw_error_sram_len
;
struct
led_classdev
led
;
struct
led_classdev
led
;
...
@@ -591,12 +598,20 @@ struct iwl_mvm {
...
@@ -591,12 +598,20 @@ struct iwl_mvm {
/* d0i3 */
/* d0i3 */
u8
d0i3_ap_sta_id
;
u8
d0i3_ap_sta_id
;
bool
d0i3_offloading
;
struct
work_struct
d0i3_exit_work
;
struct
work_struct
d0i3_exit_work
;
struct
sk_buff_head
d0i3_tx
;
/* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */
spinlock_t
d0i3_tx_lock
;
wait_queue_head_t
d0i3_exit_waitq
;
/* BT-Coex */
/* BT-Coex */
u8
bt_kill_msk
;
u8
bt_kill_msk
;
struct
iwl_bt_coex_profile_notif
last_bt_notif
;
struct
iwl_bt_coex_profile_notif
last_bt_notif
;
struct
iwl_bt_coex_ci_cmd
last_bt_ci_cmd
;
struct
iwl_bt_coex_ci_cmd
last_bt_ci_cmd
;
u32
last_ant_isol
;
u8
last_corun_lut
;
u8
bt_tx_prio
;
/* Thermal Throttling and CTkill */
/* Thermal Throttling and CTkill */
struct
iwl_mvm_tt_mgmt
thermal_throttle
;
struct
iwl_mvm_tt_mgmt
thermal_throttle
;
...
@@ -630,6 +645,7 @@ enum iwl_mvm_status {
...
@@ -630,6 +645,7 @@ enum iwl_mvm_status {
IWL_MVM_STATUS_HW_CTKILL
,
IWL_MVM_STATUS_HW_CTKILL
,
IWL_MVM_STATUS_ROC_RUNNING
,
IWL_MVM_STATUS_ROC_RUNNING
,
IWL_MVM_STATUS_IN_HW_RESTART
,
IWL_MVM_STATUS_IN_HW_RESTART
,
IWL_MVM_STATUS_IN_D0I3
,
};
};
static
inline
bool
iwl_mvm_is_radio_killed
(
struct
iwl_mvm
*
mvm
)
static
inline
bool
iwl_mvm_is_radio_killed
(
struct
iwl_mvm
*
mvm
)
...
@@ -656,6 +672,12 @@ iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id)
...
@@ -656,6 +672,12 @@ iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id)
return
iwl_mvm_sta_from_mac80211
(
sta
);
return
iwl_mvm_sta_from_mac80211
(
sta
);
}
}
static
inline
bool
iwl_mvm_is_d0i3_supported
(
struct
iwl_mvm
*
mvm
)
{
return
mvm
->
trans
->
cfg
->
d0i3
&&
(
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT
);
}
extern
const
u8
iwl_mvm_ac_to_tx_fifo
[];
extern
const
u8
iwl_mvm_ac_to_tx_fifo
[];
struct
iwl_rate_info
{
struct
iwl_rate_info
{
...
@@ -680,7 +702,10 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
...
@@ -680,7 +702,10 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
struct
ieee80211_tx_rate
*
r
);
struct
ieee80211_tx_rate
*
r
);
u8
iwl_mvm_mac80211_idx_to_hwrate
(
int
rate_idx
);
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_nic_error_log
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_dump_sram
(
struct
iwl_mvm
*
mvm
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
void
iwl_mvm_fw_error_dump
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_fw_error_sram_dump
(
struct
iwl_mvm
*
mvm
);
#endif
u8
first_antenna
(
u8
mask
);
u8
first_antenna
(
u8
mask
);
u8
iwl_mvm_next_antenna
(
struct
iwl_mvm
*
mvm
,
u8
valid
,
u8
last_idx
);
u8
iwl_mvm_next_antenna
(
struct
iwl_mvm
*
mvm
,
u8
valid
,
u8
last_idx
);
...
@@ -706,6 +731,11 @@ static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; }
...
@@ -706,6 +731,11 @@ static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; }
int
iwl_mvm_flush_tx_path
(
struct
iwl_mvm
*
mvm
,
u32
tfd_msk
,
bool
sync
);
int
iwl_mvm_flush_tx_path
(
struct
iwl_mvm
*
mvm
,
u32
tfd_msk
,
bool
sync
);
void
iwl_mvm_async_handlers_purge
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_async_handlers_purge
(
struct
iwl_mvm
*
mvm
);
static
inline
void
iwl_mvm_wait_for_async_handlers
(
struct
iwl_mvm
*
mvm
)
{
flush_work
(
&
mvm
->
async_handlers_wk
);
}
/* Statistics */
/* Statistics */
int
iwl_mvm_rx_reply_statistics
(
struct
iwl_mvm
*
mvm
,
int
iwl_mvm_rx_reply_statistics
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_rx_cmd_buffer
*
rxb
,
...
@@ -739,6 +769,9 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
...
@@ -739,6 +769,9 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct
iwl_device_cmd
*
cmd
);
struct
iwl_device_cmd
*
cmd
);
int
iwl_mvm_rx_radio_ver
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
int
iwl_mvm_rx_radio_ver
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
struct
iwl_device_cmd
*
cmd
);
int
iwl_mvm_rx_ant_coupling_notif
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
int
iwl_mvm_rx_fw_error
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
int
iwl_mvm_rx_fw_error
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
struct
iwl_device_cmd
*
cmd
);
int
iwl_mvm_rx_card_state_notif
(
struct
iwl_mvm
*
mvm
,
int
iwl_mvm_rx_card_state_notif
(
struct
iwl_mvm
*
mvm
,
...
@@ -793,7 +826,7 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
...
@@ -793,7 +826,7 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct
iwl_device_cmd
*
cmd
);
struct
iwl_device_cmd
*
cmd
);
int
iwl_mvm_rx_scan_complete
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
int
iwl_mvm_rx_scan_complete
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
struct
iwl_device_cmd
*
cmd
);
void
iwl_mvm_cancel_scan
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_cancel_scan
(
struct
iwl_mvm
*
mvm
);
/* Scheduled scan */
/* Scheduled scan */
int
iwl_mvm_rx_scan_offload_complete_notif
(
struct
iwl_mvm
*
mvm
,
int
iwl_mvm_rx_scan_offload_complete_notif
(
struct
iwl_mvm
*
mvm
,
...
@@ -807,7 +840,7 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
...
@@ -807,7 +840,7 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
struct
cfg80211_sched_scan_request
*
req
);
struct
cfg80211_sched_scan_request
*
req
);
int
iwl_mvm_sched_scan_start
(
struct
iwl_mvm
*
mvm
,
int
iwl_mvm_sched_scan_start
(
struct
iwl_mvm
*
mvm
,
struct
cfg80211_sched_scan_request
*
req
);
struct
cfg80211_sched_scan_request
*
req
);
void
iwl_mvm_sched_scan_stop
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_sched_scan_stop
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_rx_sched_scan_results
(
struct
iwl_mvm
*
mvm
,
int
iwl_mvm_rx_sched_scan_results
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
);
struct
iwl_device_cmd
*
cmd
);
...
@@ -878,10 +911,17 @@ iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
...
@@ -878,10 +911,17 @@ iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
{
}
}
#endif
#endif
void
iwl_mvm_set_wowlan_qos_seq
(
struct
iwl_mvm_sta
*
mvm_ap_sta
,
struct
iwl_wowlan_config_cmd_v2
*
cmd
);
int
iwl_mvm_send_proto_offload
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
bool
disable_offloading
,
u32
cmd_flags
);
/* D0i3 */
/* D0i3 */
void
iwl_mvm_ref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
);
void
iwl_mvm_ref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
);
void
iwl_mvm_unref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
);
void
iwl_mvm_unref
(
struct
iwl_mvm
*
mvm
,
enum
iwl_mvm_ref_type
ref_type
);
void
iwl_mvm_d0i3_enable_tx
(
struct
iwl_mvm
*
mvm
,
__le16
*
qos_seq
);
/* BT Coex */
/* BT Coex */
int
iwl_send_bt_prio_tbl
(
struct
iwl_mvm
*
mvm
);
int
iwl_send_bt_prio_tbl
(
struct
iwl_mvm
*
mvm
);
...
@@ -892,10 +932,12 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
...
@@ -892,10 +932,12 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
void
iwl_mvm_bt_rssi_event
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
void
iwl_mvm_bt_rssi_event
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
);
enum
ieee80211_rssi_event
rssi_event
);
void
iwl_mvm_bt_coex_vif_change
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_bt_coex_vif_change
(
struct
iwl_mvm
*
mvm
);
u16
iwl_mvm_
bt_
coex_agg_time_limit
(
struct
iwl_mvm
*
mvm
,
u16
iwl_mvm_coex_agg_time_limit
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
);
struct
ieee80211_sta
*
sta
);
bool
iwl_mvm_bt_coex_is_mimo_allowed
(
struct
iwl_mvm
*
mvm
,
bool
iwl_mvm_bt_coex_is_mimo_allowed
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
);
struct
ieee80211_sta
*
sta
);
u8
iwl_mvm_bt_coex_tx_prio
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_hdr
*
hdr
,
struct
ieee80211_tx_info
*
info
,
u8
ac
);
int
iwl_mvm_bt_coex_reduced_txp
(
struct
iwl_mvm
*
mvm
,
u8
sta_id
,
bool
enable
);
int
iwl_mvm_bt_coex_reduced_txp
(
struct
iwl_mvm
*
mvm
,
u8
sta_id
,
bool
enable
);
enum
iwl_bt_kill_msk
{
enum
iwl_bt_kill_msk
{
...
@@ -942,6 +984,8 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...
@@ -942,6 +984,8 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
/* Low latency */
/* Low latency */
int
iwl_mvm_update_low_latency
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
int
iwl_mvm_update_low_latency
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
bool
value
);
bool
value
);
/* get SystemLowLatencyMode - only needed for beacon threshold? */
bool
iwl_mvm_low_latency
(
struct
iwl_mvm
*
mvm
);
/* get VMACLowLatencyMode */
/* get VMACLowLatencyMode */
static
inline
bool
iwl_mvm_vif_low_latency
(
struct
iwl_mvm_vif
*
mvmvif
)
static
inline
bool
iwl_mvm_vif_low_latency
(
struct
iwl_mvm_vif
*
mvmvif
)
{
{
...
...
drivers/net/wireless/iwlwifi/mvm/offloading.c
0 → 100644
浏览文件 @
aa4a6250
/******************************************************************************
*
* 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) 2012 - 2014 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) 2012 - 2014 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.
*
*****************************************************************************/
#include <net/ipv6.h>
#include <net/addrconf.h>
#include "mvm.h"
void
iwl_mvm_set_wowlan_qos_seq
(
struct
iwl_mvm_sta
*
mvm_ap_sta
,
struct
iwl_wowlan_config_cmd_v2
*
cmd
)
{
int
i
;
/*
* For QoS counters, we store the one to use next, so subtract 0x10
* since the uCode will add 0x10 *before* using the value while we
* increment after using the value (i.e. store the next value to use).
*/
for
(
i
=
0
;
i
<
IWL_MAX_TID_COUNT
;
i
++
)
{
u16
seq
=
mvm_ap_sta
->
tid_data
[
i
].
seq_number
;
seq
-=
0x10
;
cmd
->
qos_seq
[
i
]
=
cpu_to_le16
(
seq
);
}
}
int
iwl_mvm_send_proto_offload
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
bool
disable_offloading
,
u32
cmd_flags
)
{
union
{
struct
iwl_proto_offload_cmd_v1
v1
;
struct
iwl_proto_offload_cmd_v2
v2
;
struct
iwl_proto_offload_cmd_v3_small
v3s
;
struct
iwl_proto_offload_cmd_v3_large
v3l
;
}
cmd
=
{};
struct
iwl_host_cmd
hcmd
=
{
.
id
=
PROT_OFFLOAD_CONFIG_CMD
,
.
flags
=
cmd_flags
,
.
data
[
0
]
=
&
cmd
,
.
dataflags
[
0
]
=
IWL_HCMD_DFL_DUP
,
};
struct
iwl_proto_offload_cmd_common
*
common
;
u32
enabled
=
0
,
size
;
u32
capa_flags
=
mvm
->
fw
->
ucode_capa
.
flags
;
#if IS_ENABLED(CONFIG_IPV6)
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
int
i
;
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
||
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE
)
{
struct
iwl_ns_config
*
nsc
;
struct
iwl_targ_addr
*
addrs
;
int
n_nsc
,
n_addrs
;
int
c
;
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
)
{
nsc
=
cmd
.
v3s
.
ns_config
;
n_nsc
=
IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S
;
addrs
=
cmd
.
v3s
.
targ_addrs
;
n_addrs
=
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S
;
}
else
{
nsc
=
cmd
.
v3l
.
ns_config
;
n_nsc
=
IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L
;
addrs
=
cmd
.
v3l
.
targ_addrs
;
n_addrs
=
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L
;
}
if
(
mvmvif
->
num_target_ipv6_addrs
)
enabled
|=
IWL_D3_PROTO_OFFLOAD_NS
;
/*
* For each address we have (and that will fit) fill a target
* address struct and combine for NS offload structs with the
* solicited node addresses.
*/
for
(
i
=
0
,
c
=
0
;
i
<
mvmvif
->
num_target_ipv6_addrs
&&
i
<
n_addrs
&&
c
<
n_nsc
;
i
++
)
{
struct
in6_addr
solicited_addr
;
int
j
;
addrconf_addr_solict_mult
(
&
mvmvif
->
target_ipv6_addrs
[
i
],
&
solicited_addr
);
for
(
j
=
0
;
j
<
c
;
j
++
)
if
(
ipv6_addr_cmp
(
&
nsc
[
j
].
dest_ipv6_addr
,
&
solicited_addr
)
==
0
)
break
;
if
(
j
==
c
)
c
++
;
addrs
[
i
].
addr
=
mvmvif
->
target_ipv6_addrs
[
i
];
addrs
[
i
].
config_num
=
cpu_to_le32
(
j
);
nsc
[
j
].
dest_ipv6_addr
=
solicited_addr
;
memcpy
(
nsc
[
j
].
target_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
)
cmd
.
v3s
.
num_valid_ipv6_addrs
=
cpu_to_le32
(
i
);
else
cmd
.
v3l
.
num_valid_ipv6_addrs
=
cpu_to_le32
(
i
);
}
else
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS
)
{
if
(
mvmvif
->
num_target_ipv6_addrs
)
{
enabled
|=
IWL_D3_PROTO_OFFLOAD_NS
;
memcpy
(
cmd
.
v2
.
ndp_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
BUILD_BUG_ON
(
sizeof
(
cmd
.
v2
.
target_ipv6_addr
[
0
])
!=
sizeof
(
mvmvif
->
target_ipv6_addrs
[
0
]));
for
(
i
=
0
;
i
<
min
(
mvmvif
->
num_target_ipv6_addrs
,
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2
);
i
++
)
memcpy
(
cmd
.
v2
.
target_ipv6_addr
[
i
],
&
mvmvif
->
target_ipv6_addrs
[
i
],
sizeof
(
cmd
.
v2
.
target_ipv6_addr
[
i
]));
}
else
{
if
(
mvmvif
->
num_target_ipv6_addrs
)
{
enabled
|=
IWL_D3_PROTO_OFFLOAD_NS
;
memcpy
(
cmd
.
v1
.
ndp_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
BUILD_BUG_ON
(
sizeof
(
cmd
.
v1
.
target_ipv6_addr
[
0
])
!=
sizeof
(
mvmvif
->
target_ipv6_addrs
[
0
]));
for
(
i
=
0
;
i
<
min
(
mvmvif
->
num_target_ipv6_addrs
,
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1
);
i
++
)
memcpy
(
cmd
.
v1
.
target_ipv6_addr
[
i
],
&
mvmvif
->
target_ipv6_addrs
[
i
],
sizeof
(
cmd
.
v1
.
target_ipv6_addr
[
i
]));
}
#endif
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL
)
{
common
=
&
cmd
.
v3s
.
common
;
size
=
sizeof
(
cmd
.
v3s
);
}
else
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE
)
{
common
=
&
cmd
.
v3l
.
common
;
size
=
sizeof
(
cmd
.
v3l
);
}
else
if
(
capa_flags
&
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS
)
{
common
=
&
cmd
.
v2
.
common
;
size
=
sizeof
(
cmd
.
v2
);
}
else
{
common
=
&
cmd
.
v1
.
common
;
size
=
sizeof
(
cmd
.
v1
);
}
if
(
vif
->
bss_conf
.
arp_addr_cnt
)
{
enabled
|=
IWL_D3_PROTO_OFFLOAD_ARP
;
common
->
host_ipv4_addr
=
vif
->
bss_conf
.
arp_addr_list
[
0
];
memcpy
(
common
->
arp_mac_addr
,
vif
->
addr
,
ETH_ALEN
);
}
if
(
!
disable_offloading
)
common
->
enabled
=
cpu_to_le32
(
enabled
);
hcmd
.
len
[
0
]
=
size
;
return
iwl_mvm_send_cmd
(
mvm
,
&
hcmd
);
}
drivers/net/wireless/iwlwifi/mvm/ops.c
浏览文件 @
aa4a6250
...
@@ -61,6 +61,7 @@
...
@@ -61,6 +61,7 @@
*
*
*****************************************************************************/
*****************************************************************************/
#include <linux/module.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <net/mac80211.h>
#include <net/mac80211.h>
#include "iwl-notif-wait.h"
#include "iwl-notif-wait.h"
...
@@ -78,6 +79,7 @@
...
@@ -78,6 +79,7 @@
#include "iwl-prph.h"
#include "iwl-prph.h"
#include "rs.h"
#include "rs.h"
#include "fw-api-scan.h"
#include "fw-api-scan.h"
#include "fw-error-dump.h"
#include "time-event.h"
#include "time-event.h"
/*
/*
...
@@ -220,13 +222,15 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
...
@@ -220,13 +222,15 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER
(
BT_PROFILE_NOTIFICATION
,
iwl_mvm_rx_bt_coex_notif
,
true
),
RX_HANDLER
(
BT_PROFILE_NOTIFICATION
,
iwl_mvm_rx_bt_coex_notif
,
true
),
RX_HANDLER
(
BEACON_NOTIFICATION
,
iwl_mvm_rx_beacon_notif
,
false
),
RX_HANDLER
(
BEACON_NOTIFICATION
,
iwl_mvm_rx_beacon_notif
,
false
),
RX_HANDLER
(
STATISTICS_NOTIFICATION
,
iwl_mvm_rx_statistics
,
true
),
RX_HANDLER
(
STATISTICS_NOTIFICATION
,
iwl_mvm_rx_statistics
,
true
),
RX_HANDLER
(
ANTENNA_COUPLING_NOTIFICATION
,
iwl_mvm_rx_ant_coupling_notif
,
true
),
RX_HANDLER
(
TIME_EVENT_NOTIFICATION
,
iwl_mvm_rx_time_event_notif
,
false
),
RX_HANDLER
(
TIME_EVENT_NOTIFICATION
,
iwl_mvm_rx_time_event_notif
,
false
),
RX_HANDLER
(
EOSP_NOTIFICATION
,
iwl_mvm_rx_eosp_notif
,
false
),
RX_HANDLER
(
EOSP_NOTIFICATION
,
iwl_mvm_rx_eosp_notif
,
false
),
RX_HANDLER
(
SCAN_REQUEST_CMD
,
iwl_mvm_rx_scan_response
,
false
),
RX_HANDLER
(
SCAN_REQUEST_CMD
,
iwl_mvm_rx_scan_response
,
false
),
RX_HANDLER
(
SCAN_COMPLETE_NOTIFICATION
,
iwl_mvm_rx_scan_complete
,
fals
e
),
RX_HANDLER
(
SCAN_COMPLETE_NOTIFICATION
,
iwl_mvm_rx_scan_complete
,
tru
e
),
RX_HANDLER
(
SCAN_OFFLOAD_COMPLETE
,
RX_HANDLER
(
SCAN_OFFLOAD_COMPLETE
,
iwl_mvm_rx_scan_offload_complete_notif
,
true
),
iwl_mvm_rx_scan_offload_complete_notif
,
true
),
RX_HANDLER
(
MATCH_FOUND_NOTIFICATION
,
iwl_mvm_rx_sched_scan_results
,
RX_HANDLER
(
MATCH_FOUND_NOTIFICATION
,
iwl_mvm_rx_sched_scan_results
,
...
@@ -321,6 +325,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
...
@@ -321,6 +325,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD
(
MAC_PM_POWER_TABLE
),
CMD
(
MAC_PM_POWER_TABLE
),
CMD
(
BT_COEX_CI
),
CMD
(
BT_COEX_CI
),
CMD
(
PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION
),
CMD
(
PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION
),
CMD
(
ANTENNA_COUPLING_NOTIFICATION
),
};
};
#undef CMD
#undef CMD
...
@@ -407,6 +412,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
...
@@ -407,6 +412,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
INIT_WORK
(
&
mvm
->
sta_drained_wk
,
iwl_mvm_sta_drained_wk
);
INIT_WORK
(
&
mvm
->
sta_drained_wk
,
iwl_mvm_sta_drained_wk
);
INIT_WORK
(
&
mvm
->
d0i3_exit_work
,
iwl_mvm_d0i3_exit_work
);
INIT_WORK
(
&
mvm
->
d0i3_exit_work
,
iwl_mvm_d0i3_exit_work
);
spin_lock_init
(
&
mvm
->
d0i3_tx_lock
);
skb_queue_head_init
(
&
mvm
->
d0i3_tx
);
init_waitqueue_head
(
&
mvm
->
d0i3_exit_waitq
);
SET_IEEE80211_DEV
(
mvm
->
hw
,
mvm
->
trans
->
dev
);
SET_IEEE80211_DEV
(
mvm
->
hw
,
mvm
->
trans
->
dev
);
/*
/*
...
@@ -527,6 +536,8 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
...
@@ -527,6 +536,8 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
ieee80211_unregister_hw
(
mvm
->
hw
);
ieee80211_unregister_hw
(
mvm
->
hw
);
kfree
(
mvm
->
scan_cmd
);
kfree
(
mvm
->
scan_cmd
);
vfree
(
mvm
->
fw_error_dump
);
kfree
(
mvm
->
fw_error_sram
);
kfree
(
mvm
->
mcast_filter_cmd
);
kfree
(
mvm
->
mcast_filter_cmd
);
mvm
->
mcast_filter_cmd
=
NULL
;
mvm
->
mcast_filter_cmd
=
NULL
;
...
@@ -690,7 +701,7 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
...
@@ -690,7 +701,7 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
wiphy_rfkill_set_hw_state
(
mvm
->
hw
->
wiphy
,
iwl_mvm_is_radio_killed
(
mvm
));
wiphy_rfkill_set_hw_state
(
mvm
->
hw
->
wiphy
,
iwl_mvm_is_radio_killed
(
mvm
));
}
}
static
void
iwl_mvm_set_hw_rfkill_state
(
struct
iwl_op_mode
*
op_mode
,
bool
state
)
static
bool
iwl_mvm_set_hw_rfkill_state
(
struct
iwl_op_mode
*
op_mode
,
bool
state
)
{
{
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
...
@@ -699,9 +710,9 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
...
@@ -699,9 +710,9 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
else
else
clear_bit
(
IWL_MVM_STATUS_HW_RFKILL
,
&
mvm
->
status
);
clear_bit
(
IWL_MVM_STATUS_HW_RFKILL
,
&
mvm
->
status
);
if
(
state
&&
mvm
->
cur_ucode
!=
IWL_UCODE_INIT
)
iwl_trans_stop_device
(
mvm
->
trans
);
wiphy_rfkill_set_hw_state
(
mvm
->
hw
->
wiphy
,
iwl_mvm_is_radio_killed
(
mvm
));
wiphy_rfkill_set_hw_state
(
mvm
->
hw
->
wiphy
,
iwl_mvm_is_radio_killed
(
mvm
));
return
state
&&
mvm
->
cur_ucode
!=
IWL_UCODE_INIT
;
}
}
static
void
iwl_mvm_free_skb
(
struct
iwl_op_mode
*
op_mode
,
struct
sk_buff
*
skb
)
static
void
iwl_mvm_free_skb
(
struct
iwl_op_mode
*
op_mode
,
struct
sk_buff
*
skb
)
...
@@ -797,13 +808,52 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
...
@@ -797,13 +808,52 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
}
}
}
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
void
iwl_mvm_fw_error_dump
(
struct
iwl_mvm
*
mvm
)
{
struct
iwl_fw_error_dump_file
*
dump_file
;
struct
iwl_fw_error_dump_data
*
dump_data
;
u32
file_len
;
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
mvm
->
fw_error_dump
)
return
;
file_len
=
mvm
->
fw_error_sram_len
+
sizeof
(
*
dump_file
)
+
sizeof
(
*
dump_data
);
dump_file
=
vmalloc
(
file_len
);
if
(
!
dump_file
)
return
;
mvm
->
fw_error_dump
=
dump_file
;
dump_file
->
barker
=
cpu_to_le32
(
IWL_FW_ERROR_DUMP_BARKER
);
dump_file
->
file_len
=
cpu_to_le32
(
file_len
);
dump_data
=
(
void
*
)
dump_file
->
data
;
dump_data
->
type
=
IWL_FW_ERROR_DUMP_SRAM
;
dump_data
->
len
=
cpu_to_le32
(
mvm
->
fw_error_sram_len
);
/*
* No need for lock since at the stage the FW isn't loaded. So it
* can't assert - we are the only one who can possibly be accessing
* mvm->fw_error_sram right now.
*/
memcpy
(
dump_data
->
data
,
mvm
->
fw_error_sram
,
mvm
->
fw_error_sram_len
);
}
#endif
static
void
iwl_mvm_nic_error
(
struct
iwl_op_mode
*
op_mode
)
static
void
iwl_mvm_nic_error
(
struct
iwl_op_mode
*
op_mode
)
{
{
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
iwl_mvm_dump_nic_error_log
(
mvm
);
iwl_mvm_dump_nic_error_log
(
mvm
);
if
(
!
mvm
->
restart_fw
)
iwl_mvm_dump_sram
(
mvm
);
#ifdef CONFIG_IWLWIFI_DEBUGFS
iwl_mvm_fw_error_sram_dump
(
mvm
);
#endif
iwl_mvm_nic_restart
(
mvm
);
iwl_mvm_nic_restart
(
mvm
);
}
}
...
@@ -820,8 +870,62 @@ struct iwl_d0i3_iter_data {
...
@@ -820,8 +870,62 @@ struct iwl_d0i3_iter_data {
struct
iwl_mvm
*
mvm
;
struct
iwl_mvm
*
mvm
;
u8
ap_sta_id
;
u8
ap_sta_id
;
u8
vif_count
;
u8
vif_count
;
u8
offloading_tid
;
bool
disable_offloading
;
};
};
static
bool
iwl_mvm_disallow_offloading
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
iwl_d0i3_iter_data
*
iter_data
)
{
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
struct
ieee80211_sta
*
ap_sta
;
struct
iwl_mvm_sta
*
mvmsta
;
u32
available_tids
=
0
;
u8
tid
;
if
(
WARN_ON
(
vif
->
type
!=
NL80211_IFTYPE_STATION
||
mvmvif
->
ap_sta_id
==
IWL_MVM_STATION_COUNT
))
return
false
;
ap_sta
=
rcu_dereference
(
mvm
->
fw_id_to_mac_id
[
mvmvif
->
ap_sta_id
]);
if
(
IS_ERR_OR_NULL
(
ap_sta
))
return
false
;
mvmsta
=
iwl_mvm_sta_from_mac80211
(
ap_sta
);
spin_lock_bh
(
&
mvmsta
->
lock
);
for
(
tid
=
0
;
tid
<
IWL_MAX_TID_COUNT
;
tid
++
)
{
struct
iwl_mvm_tid_data
*
tid_data
=
&
mvmsta
->
tid_data
[
tid
];
/*
* in case of pending tx packets, don't use this tid
* for offloading in order to prevent reuse of the same
* qos seq counters.
*/
if
(
iwl_mvm_tid_queued
(
tid_data
))
continue
;
if
(
tid_data
->
state
!=
IWL_AGG_OFF
)
continue
;
available_tids
|=
BIT
(
tid
);
}
spin_unlock_bh
(
&
mvmsta
->
lock
);
/*
* disallow protocol offloading if we have no available tid
* (with no pending frames and no active aggregation,
* as we don't handle "holes" properly - the scheduler needs the
* frame's seq number and TFD index to match)
*/
if
(
!
available_tids
)
return
true
;
/* for simplicity, just use the first available tid */
iter_data
->
offloading_tid
=
ffs
(
available_tids
)
-
1
;
return
false
;
}
static
void
iwl_mvm_enter_d0i3_iterator
(
void
*
_data
,
u8
*
mac
,
static
void
iwl_mvm_enter_d0i3_iterator
(
void
*
_data
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
)
struct
ieee80211_vif
*
vif
)
{
{
...
@@ -835,7 +939,16 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
...
@@ -835,7 +939,16 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
!
vif
->
bss_conf
.
assoc
)
!
vif
->
bss_conf
.
assoc
)
return
;
return
;
/*
* in case of pending tx packets or active aggregations,
* avoid offloading features in order to prevent reuse of
* the same qos seq counters.
*/
if
(
iwl_mvm_disallow_offloading
(
mvm
,
vif
,
data
))
data
->
disable_offloading
=
true
;
iwl_mvm_update_d0i3_power_mode
(
mvm
,
vif
,
true
,
flags
);
iwl_mvm_update_d0i3_power_mode
(
mvm
,
vif
,
true
,
flags
);
iwl_mvm_send_proto_offload
(
mvm
,
vif
,
data
->
disable_offloading
,
flags
);
/*
/*
* on init/association, mvm already configures POWER_TABLE_CMD
* on init/association, mvm already configures POWER_TABLE_CMD
...
@@ -847,6 +960,34 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
...
@@ -847,6 +960,34 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
data
->
vif_count
++
;
data
->
vif_count
++
;
}
}
static
void
iwl_mvm_set_wowlan_data
(
struct
iwl_mvm
*
mvm
,
struct
iwl_wowlan_config_cmd_v3
*
cmd
,
struct
iwl_d0i3_iter_data
*
iter_data
)
{
struct
ieee80211_sta
*
ap_sta
;
struct
iwl_mvm_sta
*
mvm_ap_sta
;
if
(
iter_data
->
ap_sta_id
==
IWL_MVM_STATION_COUNT
)
return
;
rcu_read_lock
();
ap_sta
=
rcu_dereference
(
mvm
->
fw_id_to_mac_id
[
iter_data
->
ap_sta_id
]);
if
(
IS_ERR_OR_NULL
(
ap_sta
))
goto
out
;
mvm_ap_sta
=
iwl_mvm_sta_from_mac80211
(
ap_sta
);
cmd
->
common
.
is_11n_connection
=
ap_sta
->
ht_cap
.
ht_supported
;
cmd
->
offloading_tid
=
iter_data
->
offloading_tid
;
/*
* The d0i3 uCode takes care of the nonqos counters,
* so configure only the qos seq ones.
*/
iwl_mvm_set_wowlan_qos_seq
(
mvm_ap_sta
,
&
cmd
->
common
);
out:
rcu_read_unlock
();
}
static
int
iwl_mvm_enter_d0i3
(
struct
iwl_op_mode
*
op_mode
)
static
int
iwl_mvm_enter_d0i3
(
struct
iwl_op_mode
*
op_mode
)
{
{
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
...
@@ -855,11 +996,14 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
...
@@ -855,11 +996,14 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
struct
iwl_d0i3_iter_data
d0i3_iter_data
=
{
struct
iwl_d0i3_iter_data
d0i3_iter_data
=
{
.
mvm
=
mvm
,
.
mvm
=
mvm
,
};
};
struct
iwl_wowlan_config_cmd
wowlan_config_cmd
=
{
struct
iwl_wowlan_config_cmd_v3
wowlan_config_cmd
=
{
.
wakeup_filter
=
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_RX_FRAME
|
.
common
=
{
IWL_WOWLAN_WAKEUP_BEACON_MISS
|
.
wakeup_filter
=
IWL_WOWLAN_WAKEUP_LINK_CHANGE
|
cpu_to_le32
(
IWL_WOWLAN_WAKEUP_RX_FRAME
|
IWL_WOWLAN_WAKEUP_BCN_FILTERING
),
IWL_WOWLAN_WAKEUP_BEACON_MISS
|
IWL_WOWLAN_WAKEUP_LINK_CHANGE
|
IWL_WOWLAN_WAKEUP_BCN_FILTERING
),
},
};
};
struct
iwl_d3_manager_config
d3_cfg_cmd
=
{
struct
iwl_d3_manager_config
d3_cfg_cmd
=
{
.
min_sleep_time
=
cpu_to_le32
(
1000
),
.
min_sleep_time
=
cpu_to_le32
(
1000
),
...
@@ -867,17 +1011,24 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
...
@@ -867,17 +1011,24 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
IWL_DEBUG_RPM
(
mvm
,
"MVM entering D0i3
\n
"
);
IWL_DEBUG_RPM
(
mvm
,
"MVM entering D0i3
\n
"
);
/* make sure we have no running tx while configuring the qos */
set_bit
(
IWL_MVM_STATUS_IN_D0I3
,
&
mvm
->
status
);
synchronize_net
();
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_enter_d0i3_iterator
,
iwl_mvm_enter_d0i3_iterator
,
&
d0i3_iter_data
);
&
d0i3_iter_data
);
if
(
d0i3_iter_data
.
vif_count
==
1
)
{
if
(
d0i3_iter_data
.
vif_count
==
1
)
{
mvm
->
d0i3_ap_sta_id
=
d0i3_iter_data
.
ap_sta_id
;
mvm
->
d0i3_ap_sta_id
=
d0i3_iter_data
.
ap_sta_id
;
mvm
->
d0i3_offloading
=
!
d0i3_iter_data
.
disable_offloading
;
}
else
{
}
else
{
WARN_ON_ONCE
(
d0i3_iter_data
.
vif_count
>
1
);
WARN_ON_ONCE
(
d0i3_iter_data
.
vif_count
>
1
);
mvm
->
d0i3_ap_sta_id
=
IWL_MVM_STATION_COUNT
;
mvm
->
d0i3_ap_sta_id
=
IWL_MVM_STATION_COUNT
;
mvm
->
d0i3_offloading
=
false
;
}
}
iwl_mvm_set_wowlan_data
(
mvm
,
&
wowlan_config_cmd
,
&
d0i3_iter_data
);
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
WOWLAN_CONFIGURATION
,
flags
,
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
WOWLAN_CONFIGURATION
,
flags
,
sizeof
(
wowlan_config_cmd
),
sizeof
(
wowlan_config_cmd
),
&
wowlan_config_cmd
);
&
wowlan_config_cmd
);
...
@@ -914,6 +1065,62 @@ static void iwl_mvm_d0i3_disconnect_iter(void *data, u8 *mac,
...
@@ -914,6 +1065,62 @@ static void iwl_mvm_d0i3_disconnect_iter(void *data, u8 *mac,
ieee80211_connection_loss
(
vif
);
ieee80211_connection_loss
(
vif
);
}
}
void
iwl_mvm_d0i3_enable_tx
(
struct
iwl_mvm
*
mvm
,
__le16
*
qos_seq
)
{
struct
ieee80211_sta
*
sta
=
NULL
;
struct
iwl_mvm_sta
*
mvm_ap_sta
;
int
i
;
bool
wake_queues
=
false
;
lockdep_assert_held
(
&
mvm
->
mutex
);
spin_lock_bh
(
&
mvm
->
d0i3_tx_lock
);
if
(
mvm
->
d0i3_ap_sta_id
==
IWL_MVM_STATION_COUNT
)
goto
out
;
IWL_DEBUG_RPM
(
mvm
,
"re-enqueue packets
\n
"
);
/* get the sta in order to update seq numbers and re-enqueue skbs */
sta
=
rcu_dereference_protected
(
mvm
->
fw_id_to_mac_id
[
mvm
->
d0i3_ap_sta_id
],
lockdep_is_held
(
&
mvm
->
mutex
));
if
(
IS_ERR_OR_NULL
(
sta
))
{
sta
=
NULL
;
goto
out
;
}
if
(
mvm
->
d0i3_offloading
&&
qos_seq
)
{
/* update qos seq numbers if offloading was enabled */
mvm_ap_sta
=
(
struct
iwl_mvm_sta
*
)
sta
->
drv_priv
;
for
(
i
=
0
;
i
<
IWL_MAX_TID_COUNT
;
i
++
)
{
u16
seq
=
le16_to_cpu
(
qos_seq
[
i
]);
/* firmware stores last-used one, we store next one */
seq
+=
0x10
;
mvm_ap_sta
->
tid_data
[
i
].
seq_number
=
seq
;
}
}
out:
/* re-enqueue (or drop) all packets */
while
(
!
skb_queue_empty
(
&
mvm
->
d0i3_tx
))
{
struct
sk_buff
*
skb
=
__skb_dequeue
(
&
mvm
->
d0i3_tx
);
if
(
!
sta
||
iwl_mvm_tx_skb
(
mvm
,
skb
,
sta
))
ieee80211_free_txskb
(
mvm
->
hw
,
skb
);
/* if the skb_queue is not empty, we need to wake queues */
wake_queues
=
true
;
}
clear_bit
(
IWL_MVM_STATUS_IN_D0I3
,
&
mvm
->
status
);
wake_up
(
&
mvm
->
d0i3_exit_waitq
);
mvm
->
d0i3_ap_sta_id
=
IWL_MVM_STATION_COUNT
;
if
(
wake_queues
)
ieee80211_wake_queues
(
mvm
->
hw
);
spin_unlock_bh
(
&
mvm
->
d0i3_tx_lock
);
}
static
void
iwl_mvm_d0i3_exit_work
(
struct
work_struct
*
wk
)
static
void
iwl_mvm_d0i3_exit_work
(
struct
work_struct
*
wk
)
{
{
struct
iwl_mvm
*
mvm
=
container_of
(
wk
,
struct
iwl_mvm
,
d0i3_exit_work
);
struct
iwl_mvm
*
mvm
=
container_of
(
wk
,
struct
iwl_mvm
,
d0i3_exit_work
);
...
@@ -924,6 +1131,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
...
@@ -924,6 +1131,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
struct
iwl_wowlan_status_v6
*
status
;
struct
iwl_wowlan_status_v6
*
status
;
int
ret
;
int
ret
;
u32
disconnection_reasons
,
wakeup_reasons
;
u32
disconnection_reasons
,
wakeup_reasons
;
__le16
*
qos_seq
=
NULL
;
mutex_lock
(
&
mvm
->
mutex
);
mutex_lock
(
&
mvm
->
mutex
);
ret
=
iwl_mvm_send_cmd
(
mvm
,
&
get_status_cmd
);
ret
=
iwl_mvm_send_cmd
(
mvm
,
&
get_status_cmd
);
...
@@ -935,6 +1143,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
...
@@ -935,6 +1143,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
status
=
(
void
*
)
get_status_cmd
.
resp_pkt
->
data
;
status
=
(
void
*
)
get_status_cmd
.
resp_pkt
->
data
;
wakeup_reasons
=
le32_to_cpu
(
status
->
wakeup_reasons
);
wakeup_reasons
=
le32_to_cpu
(
status
->
wakeup_reasons
);
qos_seq
=
status
->
qos_seq_ctr
;
IWL_DEBUG_RPM
(
mvm
,
"wakeup reasons: 0x%x
\n
"
,
wakeup_reasons
);
IWL_DEBUG_RPM
(
mvm
,
"wakeup reasons: 0x%x
\n
"
,
wakeup_reasons
);
...
@@ -948,6 +1157,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
...
@@ -948,6 +1157,7 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
iwl_free_resp
(
&
get_status_cmd
);
iwl_free_resp
(
&
get_status_cmd
);
out:
out:
iwl_mvm_d0i3_enable_tx
(
mvm
,
qos_seq
);
mutex_unlock
(
&
mvm
->
mutex
);
mutex_unlock
(
&
mvm
->
mutex
);
}
}
...
...
drivers/net/wireless/iwlwifi/mvm/power.c
浏览文件 @
aa4a6250
...
@@ -511,6 +511,7 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
...
@@ -511,6 +511,7 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
struct
iwl_power_constraint
{
struct
iwl_power_constraint
{
struct
ieee80211_vif
*
bf_vif
;
struct
ieee80211_vif
*
bf_vif
;
struct
ieee80211_vif
*
bss_vif
;
struct
ieee80211_vif
*
bss_vif
;
struct
ieee80211_vif
*
p2p_vif
;
u16
bss_phyctx_id
;
u16
bss_phyctx_id
;
u16
p2p_phyctx_id
;
u16
p2p_phyctx_id
;
bool
pm_disabled
;
bool
pm_disabled
;
...
@@ -546,6 +547,10 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
...
@@ -546,6 +547,10 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
if
(
mvmvif
->
phy_ctxt
)
if
(
mvmvif
->
phy_ctxt
)
power_iterator
->
p2p_phyctx_id
=
mvmvif
->
phy_ctxt
->
id
;
power_iterator
->
p2p_phyctx_id
=
mvmvif
->
phy_ctxt
->
id
;
/* we should have only one P2P vif */
WARN_ON
(
power_iterator
->
p2p_vif
);
power_iterator
->
p2p_vif
=
vif
;
IWL_DEBUG_POWER
(
mvm
,
"p2p: p2p_id=%d, bss_id=%d
\n
"
,
IWL_DEBUG_POWER
(
mvm
,
"p2p: p2p_id=%d, bss_id=%d
\n
"
,
power_iterator
->
p2p_phyctx_id
,
power_iterator
->
p2p_phyctx_id
,
power_iterator
->
bss_phyctx_id
);
power_iterator
->
bss_phyctx_id
);
...
@@ -633,16 +638,18 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
...
@@ -633,16 +638,18 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
return
ret
;
return
ret
;
}
}
ret
=
iwl_mvm_power_send_cmd
(
mvm
,
vif
);
if
(
constraint
.
bss_vif
)
{
if
(
ret
)
return
ret
;
if
(
constraint
.
bss_vif
&&
vif
!=
constraint
.
bss_vif
)
{
ret
=
iwl_mvm_power_send_cmd
(
mvm
,
constraint
.
bss_vif
);
ret
=
iwl_mvm_power_send_cmd
(
mvm
,
constraint
.
bss_vif
);
if
(
ret
)
if
(
ret
)
return
ret
;
return
ret
;
}
}
if
(
constraint
.
p2p_vif
)
{
ret
=
iwl_mvm_power_send_cmd
(
mvm
,
constraint
.
p2p_vif
);
if
(
ret
)
return
ret
;
}
if
(
!
constraint
.
bf_vif
)
if
(
!
constraint
.
bf_vif
)
return
0
;
return
0
;
...
...
drivers/net/wireless/iwlwifi/mvm/quota.c
浏览文件 @
aa4a6250
...
@@ -180,7 +180,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
...
@@ -180,7 +180,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
.
colors
=
{
-
1
,
-
1
,
-
1
,
-
1
},
.
colors
=
{
-
1
,
-
1
,
-
1
,
-
1
},
.
new_vif
=
newvif
,
.
new_vif
=
newvif
,
};
};
u32
ll_max_duration
;
lockdep_assert_held
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
...
@@ -199,21 +198,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
...
@@ -199,21 +198,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
iwl_mvm_quota_iterator
(
&
data
,
newvif
->
addr
,
newvif
);
iwl_mvm_quota_iterator
(
&
data
,
newvif
->
addr
,
newvif
);
}
}
switch
(
data
.
n_low_latency_bindings
)
{
case
0
:
/* no low latency - use default */
ll_max_duration
=
0
;
break
;
case
1
:
/* SingleBindingLowLatencyMode */
ll_max_duration
=
IWL_MVM_LOWLAT_SINGLE_BINDING_MAXDUR
;
break
;
case
2
:
/* DualBindingLowLatencyMode */
ll_max_duration
=
IWL_MVM_LOWLAT_DUAL_BINDING_MAXDUR
;
break
;
default:
/* MultiBindingLowLatencyMode */
ll_max_duration
=
0
;
break
;
}
/*
/*
* The FW's scheduling session consists of
* The FW's scheduling session consists of
* IWL_MVM_MAX_QUOTA fragments. Divide these fragments
* IWL_MVM_MAX_QUOTA fragments. Divide these fragments
...
@@ -278,7 +262,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
...
@@ -278,7 +262,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
* binding.
* binding.
*/
*/
cmd
.
quotas
[
idx
].
quota
=
cpu_to_le32
(
QUOTA_LOWLAT_MIN
);
cmd
.
quotas
[
idx
].
quota
=
cpu_to_le32
(
QUOTA_LOWLAT_MIN
);
else
else
cmd
.
quotas
[
idx
].
quota
=
cmd
.
quotas
[
idx
].
quota
=
cpu_to_le32
(
quota
*
data
.
n_interfaces
[
i
]);
cpu_to_le32
(
quota
*
data
.
n_interfaces
[
i
]);
...
@@ -287,11 +270,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
...
@@ -287,11 +270,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
"Binding=%d, quota=%u > max=%u
\n
"
,
"Binding=%d, quota=%u > max=%u
\n
"
,
idx
,
le32_to_cpu
(
cmd
.
quotas
[
idx
].
quota
),
QUOTA_100
);
idx
,
le32_to_cpu
(
cmd
.
quotas
[
idx
].
quota
),
QUOTA_100
);
if
(
data
.
n_interfaces
[
i
]
&&
!
data
.
low_latency
[
i
])
cmd
.
quotas
[
idx
].
max_duration
=
cpu_to_le32
(
0
);
cmd
.
quotas
[
idx
].
max_duration
=
cpu_to_le32
(
ll_max_duration
);
else
cmd
.
quotas
[
idx
].
max_duration
=
cpu_to_le32
(
0
);
idx
++
;
idx
++
;
}
}
...
...
drivers/net/wireless/iwlwifi/mvm/rs.c
浏览文件 @
aa4a6250
...
@@ -211,9 +211,9 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -211,9 +211,9 @@ static const struct rs_tx_column rs_tx_columns[] = {
.
next_columns
=
{
.
next_columns
=
{
RS_COLUMN_LEGACY_ANT_B
,
RS_COLUMN_LEGACY_ANT_B
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_MIMO2
,
RS_COLUMN_MIMO2
,
RS_COLUMN_INVALID
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_INVALID
,
},
},
},
},
[
RS_COLUMN_LEGACY_ANT_B
]
=
{
[
RS_COLUMN_LEGACY_ANT_B
]
=
{
...
@@ -221,10 +221,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -221,10 +221,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
.
ant
=
ANT_B
,
.
ant
=
ANT_B
,
.
next_columns
=
{
.
next_columns
=
{
RS_COLUMN_LEGACY_ANT_A
,
RS_COLUMN_LEGACY_ANT_A
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_MIMO2
,
RS_COLUMN_MIMO2
,
RS_COLUMN_INVALID
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_INVALID
,
},
},
},
},
[
RS_COLUMN_SISO_ANT_A
]
=
{
[
RS_COLUMN_SISO_ANT_A
]
=
{
...
@@ -234,8 +234,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -234,8 +234,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_MIMO2
,
RS_COLUMN_MIMO2
,
RS_COLUMN_SISO_ANT_A_SGI
,
RS_COLUMN_SISO_ANT_A_SGI
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
SISO_ANT_B_SGI
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
MIMO2_SGI
,
},
},
.
checks
=
{
.
checks
=
{
rs_siso_allow
,
rs_siso_allow
,
...
@@ -248,8 +248,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -248,8 +248,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_MIMO2
,
RS_COLUMN_MIMO2
,
RS_COLUMN_SISO_ANT_B_SGI
,
RS_COLUMN_SISO_ANT_B_SGI
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
SISO_ANT_A_SGI
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
MIMO2_SGI
,
},
},
.
checks
=
{
.
checks
=
{
rs_siso_allow
,
rs_siso_allow
,
...
@@ -263,8 +263,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -263,8 +263,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
RS_COLUMN_SISO_ANT_B_SGI
,
RS_COLUMN_SISO_ANT_B_SGI
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
SISO_ANT_B
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
MIMO2
,
},
},
.
checks
=
{
.
checks
=
{
rs_siso_allow
,
rs_siso_allow
,
...
@@ -279,8 +279,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -279,8 +279,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
RS_COLUMN_SISO_ANT_A_SGI
,
RS_COLUMN_SISO_ANT_A_SGI
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
SISO_ANT_A
,
RS_COLUMN_
INVALID
,
RS_COLUMN_
MIMO2
,
},
},
.
checks
=
{
.
checks
=
{
rs_siso_allow
,
rs_siso_allow
,
...
@@ -292,10 +292,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -292,10 +292,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
.
ant
=
ANT_AB
,
.
ant
=
ANT_AB
,
.
next_columns
=
{
.
next_columns
=
{
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_SISO_ANT_A_SGI
,
RS_COLUMN_SISO_ANT_B_SGI
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_MIMO2_SGI
,
RS_COLUMN_INVALID
,
RS_COLUMN_INVALID
,
RS_COLUMN_INVALID
,
},
},
.
checks
=
{
.
checks
=
{
rs_mimo_allow
,
rs_mimo_allow
,
...
@@ -307,10 +307,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
...
@@ -307,10 +307,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
.
sgi
=
true
,
.
sgi
=
true
,
.
next_columns
=
{
.
next_columns
=
{
RS_COLUMN_SISO_ANT_A_SGI
,
RS_COLUMN_SISO_ANT_A_SGI
,
RS_COLUMN_SISO_ANT_B_SGI
,
RS_COLUMN_SISO_ANT_A
,
RS_COLUMN_SISO_ANT_B
,
RS_COLUMN_MIMO2
,
RS_COLUMN_MIMO2
,
RS_COLUMN_INVALID
,
RS_COLUMN_INVALID
,
RS_COLUMN_INVALID
,
},
},
.
checks
=
{
.
checks
=
{
rs_mimo_allow
,
rs_mimo_allow
,
...
@@ -503,6 +503,14 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
...
@@ -503,6 +503,14 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
window
->
average_tpt
=
IWL_INVALID_VALUE
;
window
->
average_tpt
=
IWL_INVALID_VALUE
;
}
}
static
void
rs_rate_scale_clear_tbl_windows
(
struct
iwl_scale_tbl_info
*
tbl
)
{
int
i
;
for
(
i
=
0
;
i
<
IWL_RATE_COUNT
;
i
++
)
rs_rate_scale_clear_window
(
&
tbl
->
win
[
i
]);
}
static
inline
u8
rs_is_valid_ant
(
u8
valid_antenna
,
u8
ant_type
)
static
inline
u8
rs_is_valid_ant
(
u8
valid_antenna
,
u8
ant_type
)
{
{
return
(
ant_type
&
valid_antenna
)
==
ant_type
;
return
(
ant_type
&
valid_antenna
)
==
ant_type
;
...
@@ -566,19 +574,13 @@ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
...
@@ -566,19 +574,13 @@ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
* at this rate. window->data contains the bitmask of successful
* at this rate. window->data contains the bitmask of successful
* packets.
* packets.
*/
*/
static
int
rs_collect_tx_data
(
struct
iwl_scale_tbl_info
*
tbl
,
static
int
_rs_collect_tx_data
(
struct
iwl_scale_tbl_info
*
tbl
,
int
scale_index
,
int
attempts
,
int
successes
)
int
scale_index
,
int
attempts
,
int
successes
,
struct
iwl_rate_scale_data
*
window
)
{
{
struct
iwl_rate_scale_data
*
window
=
NULL
;
static
const
u64
mask
=
(((
u64
)
1
)
<<
(
IWL_RATE_MAX_WINDOW
-
1
));
static
const
u64
mask
=
(((
u64
)
1
)
<<
(
IWL_RATE_MAX_WINDOW
-
1
));
s32
fail_count
,
tpt
;
s32
fail_count
,
tpt
;
if
(
scale_index
<
0
||
scale_index
>=
IWL_RATE_COUNT
)
return
-
EINVAL
;
/* Select window for current tx bit rate */
window
=
&
(
tbl
->
win
[
scale_index
]);
/* Get expected throughput */
/* Get expected throughput */
tpt
=
get_expected_tpt
(
tbl
,
scale_index
);
tpt
=
get_expected_tpt
(
tbl
,
scale_index
);
...
@@ -636,6 +638,21 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
...
@@ -636,6 +638,21 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
return
0
;
return
0
;
}
}
static
int
rs_collect_tx_data
(
struct
iwl_scale_tbl_info
*
tbl
,
int
scale_index
,
int
attempts
,
int
successes
)
{
struct
iwl_rate_scale_data
*
window
=
NULL
;
if
(
scale_index
<
0
||
scale_index
>=
IWL_RATE_COUNT
)
return
-
EINVAL
;
/* Select window for current tx bit rate */
window
=
&
(
tbl
->
win
[
scale_index
]);
return
_rs_collect_tx_data
(
tbl
,
scale_index
,
attempts
,
successes
,
window
);
}
/* Convert rs_rate object into ucode rate bitmask */
/* Convert rs_rate object into ucode rate bitmask */
static
u32
ucode_rate_from_rs_rate
(
struct
iwl_mvm
*
mvm
,
static
u32
ucode_rate_from_rs_rate
(
struct
iwl_mvm
*
mvm
,
struct
rs_rate
*
rate
)
struct
rs_rate
*
rate
)
...
@@ -1361,7 +1378,6 @@ static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
...
@@ -1361,7 +1378,6 @@ static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
static
void
rs_stay_in_table
(
struct
iwl_lq_sta
*
lq_sta
,
bool
force_search
)
static
void
rs_stay_in_table
(
struct
iwl_lq_sta
*
lq_sta
,
bool
force_search
)
{
{
struct
iwl_scale_tbl_info
*
tbl
;
struct
iwl_scale_tbl_info
*
tbl
;
int
i
;
int
active_tbl
;
int
active_tbl
;
int
flush_interval_passed
=
0
;
int
flush_interval_passed
=
0
;
struct
iwl_mvm
*
mvm
;
struct
iwl_mvm
*
mvm
;
...
@@ -1422,9 +1438,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
...
@@ -1422,9 +1438,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
IWL_DEBUG_RATE
(
mvm
,
IWL_DEBUG_RATE
(
mvm
,
"LQ: stay in table clear win
\n
"
);
"LQ: stay in table clear win
\n
"
);
for
(
i
=
0
;
i
<
IWL_RATE_COUNT
;
i
++
)
rs_rate_scale_clear_tbl_windows
(
tbl
);
rs_rate_scale_clear_window
(
&
(
tbl
->
win
[
i
]));
}
}
}
}
...
@@ -1433,8 +1447,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
...
@@ -1433,8 +1447,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
* "search" table). */
* "search" table). */
if
(
lq_sta
->
rs_state
==
RS_STATE_SEARCH_CYCLE_STARTED
)
{
if
(
lq_sta
->
rs_state
==
RS_STATE_SEARCH_CYCLE_STARTED
)
{
IWL_DEBUG_RATE
(
mvm
,
"Clearing up window stats
\n
"
);
IWL_DEBUG_RATE
(
mvm
,
"Clearing up window stats
\n
"
);
for
(
i
=
0
;
i
<
IWL_RATE_COUNT
;
i
++
)
rs_rate_scale_clear_tbl_windows
(
tbl
);
rs_rate_scale_clear_window
(
&
(
tbl
->
win
[
i
]));
}
}
}
}
}
}
...
@@ -1724,7 +1737,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
...
@@ -1724,7 +1737,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
int
low
=
IWL_RATE_INVALID
;
int
low
=
IWL_RATE_INVALID
;
int
high
=
IWL_RATE_INVALID
;
int
high
=
IWL_RATE_INVALID
;
int
index
;
int
index
;
int
i
;
struct
iwl_rate_scale_data
*
window
=
NULL
;
struct
iwl_rate_scale_data
*
window
=
NULL
;
int
current_tpt
=
IWL_INVALID_VALUE
;
int
current_tpt
=
IWL_INVALID_VALUE
;
int
low_tpt
=
IWL_INVALID_VALUE
;
int
low_tpt
=
IWL_INVALID_VALUE
;
...
@@ -2009,8 +2021,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
...
@@ -2009,8 +2021,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
if
(
lq_sta
->
search_better_tbl
)
{
if
(
lq_sta
->
search_better_tbl
)
{
/* Access the "search" table, clear its history. */
/* Access the "search" table, clear its history. */
tbl
=
&
(
lq_sta
->
lq_info
[(
1
-
lq_sta
->
active_tbl
)]);
tbl
=
&
(
lq_sta
->
lq_info
[(
1
-
lq_sta
->
active_tbl
)]);
for
(
i
=
0
;
i
<
IWL_RATE_COUNT
;
i
++
)
rs_rate_scale_clear_tbl_windows
(
tbl
);
rs_rate_scale_clear_window
(
&
(
tbl
->
win
[
i
]));
/* Use new "search" start rate */
/* Use new "search" start rate */
index
=
tbl
->
rate
.
index
;
index
=
tbl
->
rate
.
index
;
...
@@ -2331,8 +2342,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
...
@@ -2331,8 +2342,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
lq_sta
->
lq
.
sta_id
=
sta_priv
->
sta_id
;
lq_sta
->
lq
.
sta_id
=
sta_priv
->
sta_id
;
for
(
j
=
0
;
j
<
LQ_SIZE
;
j
++
)
for
(
j
=
0
;
j
<
LQ_SIZE
;
j
++
)
for
(
i
=
0
;
i
<
IWL_RATE_COUNT
;
i
++
)
rs_rate_scale_clear_tbl_windows
(
&
lq_sta
->
lq_info
[
j
]);
rs_rate_scale_clear_window
(
&
lq_sta
->
lq_info
[
j
].
win
[
i
]);
lq_sta
->
flush_timer
=
0
;
lq_sta
->
flush_timer
=
0
;
...
@@ -2591,7 +2601,7 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
...
@@ -2591,7 +2601,7 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
if
(
sta
)
if
(
sta
)
lq_cmd
->
agg_time_limit
=
lq_cmd
->
agg_time_limit
=
cpu_to_le16
(
iwl_mvm_
bt_
coex_agg_time_limit
(
mvm
,
sta
));
cpu_to_le16
(
iwl_mvm_coex_agg_time_limit
(
mvm
,
sta
));
}
}
static
void
*
rs_alloc
(
struct
ieee80211_hw
*
hw
,
struct
dentry
*
debugfsdir
)
static
void
*
rs_alloc
(
struct
ieee80211_hw
*
hw
,
struct
dentry
*
debugfsdir
)
...
...
drivers/net/wireless/iwlwifi/mvm/scan.c
浏览文件 @
aa4a6250
...
@@ -70,9 +70,16 @@
...
@@ -70,9 +70,16 @@
#define IWL_PLCP_QUIET_THRESH 1
#define IWL_PLCP_QUIET_THRESH 1
#define IWL_ACTIVE_QUIET_TIME 10
#define IWL_ACTIVE_QUIET_TIME 10
#define LONG_OUT_TIME_PERIOD 600
#define SHORT_OUT_TIME_PERIOD 200
struct
iwl_mvm_scan_params
{
#define SUSPEND_TIME_PERIOD 100
u32
max_out_time
;
u32
suspend_time
;
bool
passive_fragmented
;
struct
_dwell
{
u16
passive
;
u16
active
;
}
dwell
[
IEEE80211_NUM_BANDS
];
};
static
inline
__le16
iwl_mvm_scan_rx_chain
(
struct
iwl_mvm
*
mvm
)
static
inline
__le16
iwl_mvm_scan_rx_chain
(
struct
iwl_mvm
*
mvm
)
{
{
...
@@ -90,24 +97,6 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
...
@@ -90,24 +97,6 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
return
cpu_to_le16
(
rx_chain
);
return
cpu_to_le16
(
rx_chain
);
}
}
static
inline
__le32
iwl_mvm_scan_max_out_time
(
struct
ieee80211_vif
*
vif
,
u32
flags
,
bool
is_assoc
)
{
if
(
!
is_assoc
)
return
0
;
if
(
flags
&
NL80211_SCAN_FLAG_LOW_PRIORITY
)
return
cpu_to_le32
(
ieee80211_tu_to_usec
(
SHORT_OUT_TIME_PERIOD
));
return
cpu_to_le32
(
ieee80211_tu_to_usec
(
LONG_OUT_TIME_PERIOD
));
}
static
inline
__le32
iwl_mvm_scan_suspend_time
(
struct
ieee80211_vif
*
vif
,
bool
is_assoc
)
{
if
(
!
is_assoc
)
return
0
;
return
cpu_to_le32
(
ieee80211_tu_to_usec
(
SUSPEND_TIME_PERIOD
));
}
static
inline
__le32
static
inline
__le32
iwl_mvm_scan_rxon_flags
(
struct
cfg80211_scan_request
*
req
)
iwl_mvm_scan_rxon_flags
(
struct
cfg80211_scan_request
*
req
)
{
{
...
@@ -181,15 +170,14 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
...
@@ -181,15 +170,14 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
static
void
iwl_mvm_scan_fill_channels
(
struct
iwl_scan_cmd
*
cmd
,
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
)
bool
basic_ssid
,
struct
iwl_mvm_scan_params
*
params
)
{
{
u16
passive_dwell
=
iwl_mvm_get_passive_dwell
(
req
->
channels
[
0
]
->
band
);
u16
active_dwell
=
iwl_mvm_get_active_dwell
(
req
->
channels
[
0
]
->
band
,
req
->
n_ssids
);
struct
iwl_scan_channel
*
chan
=
(
struct
iwl_scan_channel
*
)
struct
iwl_scan_channel
*
chan
=
(
struct
iwl_scan_channel
*
)
(
cmd
->
data
+
le16_to_cpu
(
cmd
->
tx_cmd
.
len
));
(
cmd
->
data
+
le16_to_cpu
(
cmd
->
tx_cmd
.
len
));
int
i
;
int
i
;
int
type
=
BIT
(
req
->
n_ssids
)
-
1
;
int
type
=
BIT
(
req
->
n_ssids
)
-
1
;
enum
ieee80211_band
band
=
req
->
channels
[
0
]
->
band
;
if
(
!
basic_ssid
)
if
(
!
basic_ssid
)
type
|=
BIT
(
req
->
n_ssids
);
type
|=
BIT
(
req
->
n_ssids
);
...
@@ -199,8 +187,8 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
...
@@ -199,8 +187,8 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
chan
->
type
=
cpu_to_le32
(
type
);
chan
->
type
=
cpu_to_le32
(
type
);
if
(
req
->
channels
[
i
]
->
flags
&
IEEE80211_CHAN_NO_IR
)
if
(
req
->
channels
[
i
]
->
flags
&
IEEE80211_CHAN_NO_IR
)
chan
->
type
&=
cpu_to_le32
(
~
SCAN_CHANNEL_TYPE_ACTIVE
);
chan
->
type
&=
cpu_to_le32
(
~
SCAN_CHANNEL_TYPE_ACTIVE
);
chan
->
active_dwell
=
cpu_to_le16
(
active_dwell
);
chan
->
active_dwell
=
cpu_to_le16
(
params
->
dwell
[
band
].
active
);
chan
->
passive_dwell
=
cpu_to_le16
(
pa
ssive_dwell
);
chan
->
passive_dwell
=
cpu_to_le16
(
pa
rams
->
dwell
[
band
].
passive
);
chan
->
iteration_count
=
cpu_to_le16
(
1
);
chan
->
iteration_count
=
cpu_to_le16
(
1
);
chan
++
;
chan
++
;
}
}
...
@@ -267,13 +255,76 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
...
@@ -267,13 +255,76 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
return
(
u16
)
len
;
return
(
u16
)
len
;
}
}
static
void
iwl_mvm_
vif_assoc
_iterator
(
void
*
data
,
u8
*
mac
,
static
void
iwl_mvm_
scan_condition
_iterator
(
void
*
data
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
)
struct
ieee80211_vif
*
vif
)
{
{
bool
*
is_assoc
=
data
;
struct
iwl_mvm_vif
*
mvmvif
=
iwl_mvm_vif_from_mac80211
(
vif
);
bool
*
global_bound
=
data
;
if
(
vif
->
bss_conf
.
assoc
)
if
(
mvmvif
->
phy_ctxt
&&
mvmvif
->
phy_ctxt
->
id
<
MAX_PHYS
)
*
is_assoc
=
true
;
*
global_bound
=
true
;
}
static
void
iwl_mvm_scan_calc_params
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
int
n_ssids
,
struct
iwl_mvm_scan_params
*
params
)
{
bool
global_bound
=
false
;
enum
ieee80211_band
band
;
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_scan_condition_iterator
,
&
global_bound
);
/*
* Under low latency traffic passive scan is fragmented meaning
* that dwell on a particular channel will be fragmented. Each fragment
* dwell time is 20ms and fragments period is 105ms. Skipping to next
* channel will be delayed by the same period - 105ms. So suspend_time
* parameter describing both fragments and channels skipping periods is
* set to 105ms. This value is chosen so that overall passive scan
* duration will not be too long. Max_out_time in this case is set to
* 70ms, so for active scanning operating channel will be left for 70ms
* while for passive still for 20ms (fragment dwell).
*/
if
(
global_bound
)
{
if
(
!
iwl_mvm_low_latency
(
mvm
))
{
params
->
suspend_time
=
ieee80211_tu_to_usec
(
100
);
params
->
max_out_time
=
ieee80211_tu_to_usec
(
600
);
}
else
{
params
->
suspend_time
=
ieee80211_tu_to_usec
(
105
);
/* P2P doesn't support fragmented passive scan, so
* configure max_out_time to be at least longest dwell
* time for passive scan.
*/
if
(
vif
->
type
==
NL80211_IFTYPE_STATION
&&
!
vif
->
p2p
)
{
params
->
max_out_time
=
ieee80211_tu_to_usec
(
70
);
params
->
passive_fragmented
=
true
;
}
else
{
u32
passive_dwell
;
/*
* Use band G so that passive channel dwell time
* will be assigned with maximum value.
*/
band
=
IEEE80211_BAND_2GHZ
;
passive_dwell
=
iwl_mvm_get_passive_dwell
(
band
);
params
->
max_out_time
=
ieee80211_tu_to_usec
(
passive_dwell
);
}
}
}
for
(
band
=
IEEE80211_BAND_2GHZ
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
if
(
params
->
passive_fragmented
)
params
->
dwell
[
band
].
passive
=
20
;
else
params
->
dwell
[
band
].
passive
=
iwl_mvm_get_passive_dwell
(
band
);
params
->
dwell
[
band
].
active
=
iwl_mvm_get_active_dwell
(
band
,
n_ssids
);
}
}
}
int
iwl_mvm_scan_request
(
struct
iwl_mvm
*
mvm
,
int
iwl_mvm_scan_request
(
struct
iwl_mvm
*
mvm
,
...
@@ -288,13 +339,13 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
...
@@ -288,13 +339,13 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
.
dataflags
=
{
IWL_HCMD_DFL_NOCOPY
,
},
.
dataflags
=
{
IWL_HCMD_DFL_NOCOPY
,
},
};
};
struct
iwl_scan_cmd
*
cmd
=
mvm
->
scan_cmd
;
struct
iwl_scan_cmd
*
cmd
=
mvm
->
scan_cmd
;
bool
is_assoc
=
false
;
int
ret
;
int
ret
;
u32
status
;
u32
status
;
int
ssid_len
=
0
;
int
ssid_len
=
0
;
u8
*
ssid
=
NULL
;
u8
*
ssid
=
NULL
;
bool
basic_ssid
=
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
bool
basic_ssid
=
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID
);
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID
);
struct
iwl_mvm_scan_params
params
=
{};
lockdep_assert_held
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
BUG_ON
(
mvm
->
scan_cmd
==
NULL
);
BUG_ON
(
mvm
->
scan_cmd
==
NULL
);
...
@@ -304,17 +355,18 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
...
@@ -304,17 +355,18 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
memset
(
cmd
,
0
,
sizeof
(
struct
iwl_scan_cmd
)
+
memset
(
cmd
,
0
,
sizeof
(
struct
iwl_scan_cmd
)
+
mvm
->
fw
->
ucode_capa
.
max_probe_length
+
mvm
->
fw
->
ucode_capa
.
max_probe_length
+
(
MAX_NUM_SCAN_CHANNELS
*
sizeof
(
struct
iwl_scan_channel
)));
(
MAX_NUM_SCAN_CHANNELS
*
sizeof
(
struct
iwl_scan_channel
)));
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_vif_assoc_iterator
,
&
is_assoc
);
cmd
->
channel_count
=
(
u8
)
req
->
n_channels
;
cmd
->
channel_count
=
(
u8
)
req
->
n_channels
;
cmd
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
cmd
->
quiet_time
=
cpu_to_le16
(
IWL_ACTIVE_QUIET_TIME
);
cmd
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
cmd
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
cmd
->
rxchain_sel_flags
=
iwl_mvm_scan_rx_chain
(
mvm
);
cmd
->
rxchain_sel_flags
=
iwl_mvm_scan_rx_chain
(
mvm
);
cmd
->
max_out_time
=
iwl_mvm_scan_max_out_time
(
vif
,
req
->
flags
,
is_assoc
);
iwl_mvm_scan_calc_params
(
mvm
,
vif
,
req
->
n_ssids
,
&
params
);
cmd
->
suspend_time
=
iwl_mvm_scan_suspend_time
(
vif
,
is_assoc
);
cmd
->
max_out_time
=
cpu_to_le32
(
params
.
max_out_time
);
cmd
->
suspend_time
=
cpu_to_le32
(
params
.
suspend_time
);
if
(
params
.
passive_fragmented
)
cmd
->
scan_flags
|=
SCAN_FLAGS_FRAGMENTED_SCAN
;
cmd
->
rxon_flags
=
iwl_mvm_scan_rxon_flags
(
req
);
cmd
->
rxon_flags
=
iwl_mvm_scan_rxon_flags
(
req
);
cmd
->
filter_flags
=
cpu_to_le32
(
MAC_FILTER_ACCEPT_GRP
|
cmd
->
filter_flags
=
cpu_to_le32
(
MAC_FILTER_ACCEPT_GRP
|
MAC_FILTER_IN_BEACON
);
MAC_FILTER_IN_BEACON
);
...
@@ -360,7 +412,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
...
@@ -360,7 +412,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
req
->
ie
,
req
->
ie_len
,
req
->
ie
,
req
->
ie_len
,
mvm
->
fw
->
ucode_capa
.
max_probe_length
));
mvm
->
fw
->
ucode_capa
.
max_probe_length
));
iwl_mvm_scan_fill_channels
(
cmd
,
req
,
basic_ssid
);
iwl_mvm_scan_fill_channels
(
cmd
,
req
,
basic_ssid
,
&
params
);
cmd
->
len
=
cpu_to_le16
(
sizeof
(
struct
iwl_scan_cmd
)
+
cmd
->
len
=
cpu_to_le16
(
sizeof
(
struct
iwl_scan_cmd
)
+
le16_to_cpu
(
cmd
->
tx_cmd
.
len
)
+
le16_to_cpu
(
cmd
->
tx_cmd
.
len
)
+
...
@@ -402,10 +454,13 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
...
@@ -402,10 +454,13 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_scan_complete_notif
*
notif
=
(
void
*
)
pkt
->
data
;
struct
iwl_scan_complete_notif
*
notif
=
(
void
*
)
pkt
->
data
;
lockdep_assert_held
(
&
mvm
->
mutex
);
IWL_DEBUG_SCAN
(
mvm
,
"Scan complete: status=0x%x scanned channels=%d
\n
"
,
IWL_DEBUG_SCAN
(
mvm
,
"Scan complete: status=0x%x scanned channels=%d
\n
"
,
notif
->
status
,
notif
->
scanned_channels
);
notif
->
status
,
notif
->
scanned_channels
);
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
if
(
mvm
->
scan_status
==
IWL_MVM_SCAN_OS
)
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
ieee80211_scan_completed
(
mvm
->
hw
,
notif
->
status
!=
SCAN_COMP_STATUS_OK
);
ieee80211_scan_completed
(
mvm
->
hw
,
notif
->
status
!=
SCAN_COMP_STATUS_OK
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_SCAN
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_SCAN
);
...
@@ -466,7 +521,7 @@ static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
...
@@ -466,7 +521,7 @@ static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
};
};
}
}
void
iwl_mvm_cancel_scan
(
struct
iwl_mvm
*
mvm
)
int
iwl_mvm_cancel_scan
(
struct
iwl_mvm
*
mvm
)
{
{
struct
iwl_notification_wait
wait_scan_abort
;
struct
iwl_notification_wait
wait_scan_abort
;
static
const
u8
scan_abort_notif
[]
=
{
SCAN_ABORT_CMD
,
static
const
u8
scan_abort_notif
[]
=
{
SCAN_ABORT_CMD
,
...
@@ -474,13 +529,13 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
...
@@ -474,13 +529,13 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
int
ret
;
int
ret
;
if
(
mvm
->
scan_status
==
IWL_MVM_SCAN_NONE
)
if
(
mvm
->
scan_status
==
IWL_MVM_SCAN_NONE
)
return
;
return
0
;
if
(
iwl_mvm_is_radio_killed
(
mvm
))
{
if
(
iwl_mvm_is_radio_killed
(
mvm
))
{
ieee80211_scan_completed
(
mvm
->
hw
,
true
);
ieee80211_scan_completed
(
mvm
->
hw
,
true
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_SCAN
);
iwl_mvm_unref
(
mvm
,
IWL_MVM_REF_SCAN
);
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
return
;
return
0
;
}
}
iwl_init_notification_wait
(
&
mvm
->
notif_wait
,
&
wait_scan_abort
,
iwl_init_notification_wait
(
&
mvm
->
notif_wait
,
&
wait_scan_abort
,
...
@@ -495,14 +550,11 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
...
@@ -495,14 +550,11 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
goto
out_remove_notif
;
goto
out_remove_notif
;
}
}
ret
=
iwl_wait_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_abort
,
1
*
HZ
);
return
iwl_wait_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_abort
,
HZ
);
if
(
ret
)
IWL_ERR
(
mvm
,
"%s - failed on timeout
\n
"
,
__func__
);
return
;
out_remove_notif:
out_remove_notif:
iwl_remove_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_abort
);
iwl_remove_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_abort
);
return
ret
;
}
}
int
iwl_mvm_rx_scan_offload_complete_notif
(
struct
iwl_mvm
*
mvm
,
int
iwl_mvm_rx_scan_offload_complete_notif
(
struct
iwl_mvm
*
mvm
,
...
@@ -519,10 +571,11 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
...
@@ -519,10 +571,11 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
scan_notif
->
status
==
IWL_SCAN_OFFLOAD_COMPLETED
?
scan_notif
->
status
==
IWL_SCAN_OFFLOAD_COMPLETED
?
"completed"
:
"aborted"
);
"completed"
:
"aborted"
);
/*
might already be something else again, don't reset if so
*/
/*
only call mac80211 completion if the stop was initiated by FW
*/
if
(
mvm
->
scan_status
==
IWL_MVM_SCAN_SCHED
)
if
(
mvm
->
scan_status
==
IWL_MVM_SCAN_SCHED
)
{
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
ieee80211_sched_scan_stopped
(
mvm
->
hw
);
ieee80211_sched_scan_stopped
(
mvm
->
hw
);
}
return
0
;
return
0
;
}
}
...
@@ -553,14 +606,9 @@ static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
...
@@ -553,14 +606,9 @@ static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
static
void
iwl_build_scan_cmd
(
struct
iwl_mvm
*
mvm
,
static
void
iwl_build_scan_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_sched_scan_request
*
req
,
struct
cfg80211_sched_scan_request
*
req
,
struct
iwl_scan_offload_cmd
*
scan
)
struct
iwl_scan_offload_cmd
*
scan
,
struct
iwl_mvm_scan_params
*
params
)
{
{
bool
is_assoc
=
false
;
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_vif_assoc_iterator
,
&
is_assoc
);
scan
->
channel_count
=
scan
->
channel_count
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
+
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
+
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
...
@@ -568,13 +616,17 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
...
@@ -568,13 +616,17 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
scan
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
scan
->
quiet_plcp_th
=
cpu_to_le16
(
IWL_PLCP_QUIET_THRESH
);
scan
->
good_CRC_th
=
IWL_GOOD_CRC_TH_DEFAULT
;
scan
->
good_CRC_th
=
IWL_GOOD_CRC_TH_DEFAULT
;
scan
->
rx_chain
=
iwl_mvm_scan_rx_chain
(
mvm
);
scan
->
rx_chain
=
iwl_mvm_scan_rx_chain
(
mvm
);
scan
->
max_out_time
=
iwl_mvm_scan_max_out_time
(
vif
,
req
->
flags
,
is_assoc
);
scan
->
max_out_time
=
cpu_to_le32
(
params
->
max_out_time
);
scan
->
suspend_time
=
iwl_mvm_scan_suspend_time
(
vif
,
is_assoc
);
scan
->
suspend_time
=
cpu_to_le32
(
params
->
suspend_time
);
scan
->
filter_flags
|=
cpu_to_le32
(
MAC_FILTER_ACCEPT_GRP
|
scan
->
filter_flags
|=
cpu_to_le32
(
MAC_FILTER_ACCEPT_GRP
|
MAC_FILTER_IN_BEACON
);
MAC_FILTER_IN_BEACON
);
scan
->
scan_type
=
cpu_to_le32
(
SCAN_TYPE_BACKGROUND
);
scan
->
scan_type
=
cpu_to_le32
(
SCAN_TYPE_BACKGROUND
);
scan
->
rep_count
=
cpu_to_le32
(
1
);
scan
->
rep_count
=
cpu_to_le32
(
1
);
if
(
params
->
passive_fragmented
)
scan
->
scan_flags
|=
SCAN_FLAGS_FRAGMENTED_SCAN
;
}
}
static
int
iwl_ssid_exist
(
u8
*
ssid
,
u8
ssid_len
,
struct
iwl_ssid_ie
*
ssid_list
)
static
int
iwl_ssid_exist
(
u8
*
ssid
,
u8
ssid_len
,
struct
iwl_ssid_ie
*
ssid_list
)
...
@@ -639,12 +691,11 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
...
@@ -639,12 +691,11 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
struct
iwl_scan_channel_cfg
*
channels
,
struct
iwl_scan_channel_cfg
*
channels
,
enum
ieee80211_band
band
,
enum
ieee80211_band
band
,
int
*
head
,
int
*
tail
,
int
*
head
,
int
*
tail
,
u32
ssid_bitmap
)
u32
ssid_bitmap
,
struct
iwl_mvm_scan_params
*
params
)
{
{
struct
ieee80211_supported_band
*
s_band
;
struct
ieee80211_supported_band
*
s_band
;
int
n_probes
=
req
->
n_ssids
;
int
n_channels
=
req
->
n_channels
;
int
n_channels
=
req
->
n_channels
;
u8
active_dwell
,
passive_dwell
;
int
i
,
j
,
index
=
0
;
int
i
,
j
,
index
=
0
;
bool
partial
;
bool
partial
;
...
@@ -654,8 +705,6 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
...
@@ -654,8 +705,6 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
* to scan. So add requested channels to head of the list and others to
* to scan. So add requested channels to head of the list and others to
* the end.
* 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
];
s_band
=
&
mvm
->
nvm_data
->
bands
[
band
];
for
(
i
=
0
;
i
<
s_band
->
n_channels
&&
*
head
<=
*
tail
;
i
++
)
{
for
(
i
=
0
;
i
<
s_band
->
n_channels
&&
*
head
<=
*
tail
;
i
++
)
{
...
@@ -679,8 +728,8 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
...
@@ -679,8 +728,8 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
channels
->
channel_number
[
index
]
=
channels
->
channel_number
[
index
]
=
cpu_to_le16
(
ieee80211_frequency_to_channel
(
cpu_to_le16
(
ieee80211_frequency_to_channel
(
s_band
->
channels
[
i
].
center_freq
));
s_band
->
channels
[
i
].
center_freq
));
channels
->
dwell_time
[
index
][
0
]
=
active_dwell
;
channels
->
dwell_time
[
index
][
0
]
=
params
->
dwell
[
band
].
active
;
channels
->
dwell_time
[
index
][
1
]
=
pa
ssive_dwell
;
channels
->
dwell_time
[
index
][
1
]
=
pa
rams
->
dwell
[
band
].
passive
;
channels
->
iter_count
[
index
]
=
cpu_to_le16
(
1
);
channels
->
iter_count
[
index
]
=
cpu_to_le16
(
1
);
channels
->
iter_interval
[
index
]
=
0
;
channels
->
iter_interval
[
index
]
=
0
;
...
@@ -709,7 +758,6 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
...
@@ -709,7 +758,6 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
struct
cfg80211_sched_scan_request
*
req
,
struct
cfg80211_sched_scan_request
*
req
,
struct
ieee80211_sched_scan_ies
*
ies
)
struct
ieee80211_sched_scan_ies
*
ies
)
{
{
int
supported_bands
=
0
;
int
band_2ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
;
int
band_2ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_2GHZ
].
n_channels
;
int
band_5ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
int
band_5ghz
=
mvm
->
nvm_data
->
bands
[
IEEE80211_BAND_5GHZ
].
n_channels
;
int
head
=
0
;
int
head
=
0
;
...
@@ -723,22 +771,19 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
...
@@ -723,22 +771,19 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
.
id
=
SCAN_OFFLOAD_CONFIG_CMD
,
.
id
=
SCAN_OFFLOAD_CONFIG_CMD
,
.
flags
=
CMD_SYNC
,
.
flags
=
CMD_SYNC
,
};
};
struct
iwl_mvm_scan_params
params
=
{};
lockdep_assert_held
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
band_2ghz
)
supported_bands
++
;
if
(
band_5ghz
)
supported_bands
++
;
cmd_len
=
sizeof
(
struct
iwl_scan_offload_cfg
)
+
cmd_len
=
sizeof
(
struct
iwl_scan_offload_cfg
)
+
supported_bands
*
SCAN_OFFLOAD_PROBE_REQ_SIZE
;
2
*
SCAN_OFFLOAD_PROBE_REQ_SIZE
;
scan_cfg
=
kzalloc
(
cmd_len
,
GFP_KERNEL
);
scan_cfg
=
kzalloc
(
cmd_len
,
GFP_KERNEL
);
if
(
!
scan_cfg
)
if
(
!
scan_cfg
)
return
-
ENOMEM
;
return
-
ENOMEM
;
iwl_build_scan_cmd
(
mvm
,
vif
,
req
,
&
scan_cfg
->
scan_cmd
);
iwl_mvm_scan_calc_params
(
mvm
,
vif
,
req
->
n_ssids
,
&
params
);
iwl_build_scan_cmd
(
mvm
,
vif
,
req
,
&
scan_cfg
->
scan_cmd
,
&
params
);
scan_cfg
->
scan_cmd
.
len
=
cpu_to_le16
(
cmd_len
);
scan_cfg
->
scan_cmd
.
len
=
cpu_to_le16
(
cmd_len
);
iwl_scan_offload_build_ssid
(
req
,
&
scan_cfg
->
scan_cmd
,
&
ssid_bitmap
);
iwl_scan_offload_build_ssid
(
req
,
&
scan_cfg
->
scan_cmd
,
&
ssid_bitmap
);
...
@@ -750,7 +795,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
...
@@ -750,7 +795,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
scan_cfg
->
data
);
scan_cfg
->
data
);
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
IEEE80211_BAND_2GHZ
,
&
head
,
&
tail
,
IEEE80211_BAND_2GHZ
,
&
head
,
&
tail
,
ssid_bitmap
);
ssid_bitmap
,
&
params
);
}
}
if
(
band_5ghz
)
{
if
(
band_5ghz
)
{
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
iwl_scan_offload_build_tx_cmd
(
mvm
,
vif
,
ies
,
...
@@ -760,7 +805,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
...
@@ -760,7 +805,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
SCAN_OFFLOAD_PROBE_REQ_SIZE
);
SCAN_OFFLOAD_PROBE_REQ_SIZE
);
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
iwl_build_channel_cfg
(
mvm
,
req
,
&
scan_cfg
->
channel_cfg
,
IEEE80211_BAND_5GHZ
,
&
head
,
&
tail
,
IEEE80211_BAND_5GHZ
,
&
head
,
&
tail
,
ssid_bitmap
);
ssid_bitmap
,
&
params
);
}
}
cmd
.
data
[
0
]
=
scan_cfg
;
cmd
.
data
[
0
]
=
scan_cfg
;
...
@@ -900,26 +945,49 @@ static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
...
@@ -900,26 +945,49 @@ static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
* microcode has notified us that a scan is completed.
* microcode has notified us that a scan is completed.
*/
*/
IWL_DEBUG_SCAN
(
mvm
,
"SCAN OFFLOAD ABORT ret %d.
\n
"
,
status
);
IWL_DEBUG_SCAN
(
mvm
,
"SCAN OFFLOAD ABORT ret %d.
\n
"
,
status
);
ret
=
-
E
IO
;
ret
=
-
E
NOENT
;
}
}
return
ret
;
return
ret
;
}
}
void
iwl_mvm_sched_scan_stop
(
struct
iwl_mvm
*
mvm
)
int
iwl_mvm_sched_scan_stop
(
struct
iwl_mvm
*
mvm
)
{
{
int
ret
;
int
ret
;
struct
iwl_notification_wait
wait_scan_done
;
static
const
u8
scan_done_notif
[]
=
{
SCAN_OFFLOAD_COMPLETE
,
};
lockdep_assert_held
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
mvm
->
scan_status
!=
IWL_MVM_SCAN_SCHED
)
{
if
(
mvm
->
scan_status
!=
IWL_MVM_SCAN_SCHED
)
{
IWL_DEBUG_SCAN
(
mvm
,
"No offloaded scan to stop
\n
"
);
IWL_DEBUG_SCAN
(
mvm
,
"No offloaded scan to stop
\n
"
);
return
;
return
0
;
}
}
iwl_init_notification_wait
(
&
mvm
->
notif_wait
,
&
wait_scan_done
,
scan_done_notif
,
ARRAY_SIZE
(
scan_done_notif
),
NULL
,
NULL
);
ret
=
iwl_mvm_send_sched_scan_abort
(
mvm
);
ret
=
iwl_mvm_send_sched_scan_abort
(
mvm
);
if
(
ret
)
if
(
ret
)
{
IWL_DEBUG_SCAN
(
mvm
,
"Send stop offload scan failed %d
\n
"
,
ret
);
IWL_DEBUG_SCAN
(
mvm
,
"Send stop offload scan failed %d
\n
"
,
ret
);
else
iwl_remove_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_done
);
IWL_DEBUG_SCAN
(
mvm
,
"Successfully sent stop offload scan
\n
"
);
return
ret
;
}
IWL_DEBUG_SCAN
(
mvm
,
"Successfully sent stop offload scan
\n
"
);
ret
=
iwl_wait_notification
(
&
mvm
->
notif_wait
,
&
wait_scan_done
,
1
*
HZ
);
if
(
ret
)
return
ret
;
/*
* Clear the scan status so the next scan requests will succeed. This
* also ensures the Rx handler doesn't do anything, as the scan was
* stopped from above.
*/
mvm
->
scan_status
=
IWL_MVM_SCAN_NONE
;
return
0
;
}
}
drivers/net/wireless/iwlwifi/mvm/sta.c
浏览文件 @
aa4a6250
...
@@ -851,7 +851,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
...
@@ -851,7 +851,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
return
ret
;
return
ret
;
}
}
static
const
u8
tid_to_mac80211_ac
[]
=
{
const
u8
tid_to_mac80211_ac
[]
=
{
IEEE80211_AC_BE
,
IEEE80211_AC_BE
,
IEEE80211_AC_BK
,
IEEE80211_AC_BK
,
IEEE80211_AC_BK
,
IEEE80211_AC_BK
,
...
@@ -902,10 +902,18 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...
@@ -902,10 +902,18 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return
-
EIO
;
return
-
EIO
;
}
}
spin_lock_bh
(
&
mvmsta
->
lock
);
/* possible race condition - we entered D0i3 while starting agg */
if
(
test_bit
(
IWL_MVM_STATUS_IN_D0I3
,
&
mvm
->
status
))
{
spin_unlock_bh
(
&
mvmsta
->
lock
);
IWL_ERR
(
mvm
,
"Entered D0i3 while starting Tx agg
\n
"
);
return
-
EIO
;
}
/* the new tx queue is still connected to the same mac80211 queue */
/* the new tx queue is still connected to the same mac80211 queue */
mvm
->
queue_to_mac80211
[
txq_id
]
=
vif
->
hw_queue
[
tid_to_mac80211_ac
[
tid
]];
mvm
->
queue_to_mac80211
[
txq_id
]
=
vif
->
hw_queue
[
tid_to_mac80211_ac
[
tid
]];
spin_lock_bh
(
&
mvmsta
->
lock
);
tid_data
=
&
mvmsta
->
tid_data
[
tid
];
tid_data
=
&
mvmsta
->
tid_data
[
tid
];
tid_data
->
ssn
=
IEEE80211_SEQ_TO_SN
(
tid_data
->
seq_number
);
tid_data
->
ssn
=
IEEE80211_SEQ_TO_SN
(
tid_data
->
seq_number
);
tid_data
->
txq_id
=
txq_id
;
tid_data
->
txq_id
=
txq_id
;
...
...
drivers/net/wireless/iwlwifi/mvm/tx.c
浏览文件 @
aa4a6250
...
@@ -79,6 +79,7 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
...
@@ -79,6 +79,7 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
__le16
fc
=
hdr
->
frame_control
;
__le16
fc
=
hdr
->
frame_control
;
u32
tx_flags
=
le32_to_cpu
(
tx_cmd
->
tx_flags
);
u32
tx_flags
=
le32_to_cpu
(
tx_cmd
->
tx_flags
);
u32
len
=
skb
->
len
+
FCS_LEN
;
u32
len
=
skb
->
len
+
FCS_LEN
;
u8
ac
;
if
(
!
(
info
->
flags
&
IEEE80211_TX_CTL_NO_ACK
))
if
(
!
(
info
->
flags
&
IEEE80211_TX_CTL_NO_ACK
))
tx_flags
|=
TX_CMD_FLG_ACK
;
tx_flags
|=
TX_CMD_FLG_ACK
;
...
@@ -90,13 +91,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
...
@@ -90,13 +91,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
else
if
(
ieee80211_is_back_req
(
fc
))
else
if
(
ieee80211_is_back_req
(
fc
))
tx_flags
|=
TX_CMD_FLG_ACK
|
TX_CMD_FLG_BAR
;
tx_flags
|=
TX_CMD_FLG_ACK
|
TX_CMD_FLG_BAR
;
/* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
if
(
info
->
band
==
IEEE80211_BAND_2GHZ
&&
(
info
->
control
.
flags
&
IEEE80211_TX_CTRL_PORT_CTRL_PROTO
||
is_multicast_ether_addr
(
hdr
->
addr1
)
||
ieee80211_is_back_req
(
fc
)
||
ieee80211_is_mgmt
(
fc
)))
tx_flags
|=
TX_CMD_FLG_BT_DIS
;
if
(
ieee80211_has_morefrags
(
fc
))
if
(
ieee80211_has_morefrags
(
fc
))
tx_flags
|=
TX_CMD_FLG_MORE_FRAG
;
tx_flags
|=
TX_CMD_FLG_MORE_FRAG
;
...
@@ -112,6 +106,11 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
...
@@ -112,6 +106,11 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
tx_flags
&=
~
TX_CMD_FLG_SEQ_CTL
;
tx_flags
&=
~
TX_CMD_FLG_SEQ_CTL
;
}
}
/* tid_tspec will default to 0 = BE when QOS isn't enabled */
ac
=
tid_to_mac80211_ac
[
tx_cmd
->
tid_tspec
];
tx_flags
|=
iwl_mvm_bt_coex_tx_prio
(
mvm
,
hdr
,
info
,
ac
)
<<
TX_CMD_FLG_BT_PRIO_POS
;
if
(
ieee80211_is_mgmt
(
fc
))
{
if
(
ieee80211_is_mgmt
(
fc
))
{
if
(
ieee80211_is_assoc_req
(
fc
)
||
ieee80211_is_reassoc_req
(
fc
))
if
(
ieee80211_is_assoc_req
(
fc
)
||
ieee80211_is_reassoc_req
(
fc
))
tx_cmd
->
pm_frame_timeout
=
cpu_to_le16
(
3
);
tx_cmd
->
pm_frame_timeout
=
cpu_to_le16
(
3
);
...
@@ -128,9 +127,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
...
@@ -128,9 +127,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
tx_cmd
->
pm_frame_timeout
=
0
;
tx_cmd
->
pm_frame_timeout
=
0
;
}
}
if
(
info
->
flags
&
IEEE80211_TX_CTL_AMPDU
)
tx_flags
|=
TX_CMD_FLG_PROT_REQUIRE
;
if
(
ieee80211_is_data
(
fc
)
&&
len
>
mvm
->
rts_threshold
&&
if
(
ieee80211_is_data
(
fc
)
&&
len
>
mvm
->
rts_threshold
&&
!
is_multicast_ether_addr
(
ieee80211_get_DA
(
hdr
)))
!
is_multicast_ether_addr
(
ieee80211_get_DA
(
hdr
)))
tx_flags
|=
TX_CMD_FLG_PROT_REQUIRE
;
tx_flags
|=
TX_CMD_FLG_PROT_REQUIRE
;
...
...
drivers/net/wireless/iwlwifi/mvm/utils.c
浏览文件 @
aa4a6250
...
@@ -516,33 +516,26 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
...
@@ -516,33 +516,26 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
iwl_mvm_dump_umac_error_log
(
mvm
);
iwl_mvm_dump_umac_error_log
(
mvm
);
}
}
void
iwl_mvm_
dump_sram
(
struct
iwl_mvm
*
mvm
)
void
iwl_mvm_
fw_error_sram_dump
(
struct
iwl_mvm
*
mvm
)
{
{
const
struct
fw_img
*
img
;
const
struct
fw_img
*
img
;
int
ofs
,
len
=
0
;
u32
ofs
,
sram_len
;
int
i
;
void
*
sram
;
__le32
*
buf
;
if
(
!
mvm
->
ucode_loaded
)
if
(
!
mvm
->
ucode_loaded
||
mvm
->
fw_error_sram
)
return
;
return
;
img
=
&
mvm
->
fw
->
img
[
mvm
->
cur_ucode
];
img
=
&
mvm
->
fw
->
img
[
mvm
->
cur_ucode
];
ofs
=
img
->
sec
[
IWL_UCODE_SECTION_DATA
].
offset
;
ofs
=
img
->
sec
[
IWL_UCODE_SECTION_DATA
].
offset
;
len
=
img
->
sec
[
IWL_UCODE_SECTION_DATA
].
len
;
sram_
len
=
img
->
sec
[
IWL_UCODE_SECTION_DATA
].
len
;
buf
=
kzalloc
(
len
,
GFP_ATOMIC
);
sram
=
kzalloc
(
sram_
len
,
GFP_ATOMIC
);
if
(
!
buf
)
if
(
!
sram
)
return
;
return
;
iwl_trans_read_mem_bytes
(
mvm
->
trans
,
ofs
,
buf
,
len
);
iwl_trans_read_mem_bytes
(
mvm
->
trans
,
ofs
,
sram
,
sram_len
);
len
=
len
>>
2
;
mvm
->
fw_error_sram
=
sram
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
mvm
->
fw_error_sram_len
=
sram_len
;
IWL_ERR
(
mvm
,
"0x%08X
\n
"
,
le32_to_cpu
(
buf
[
i
]));
/* Add a small delay to let syslog catch up */
udelay
(
10
);
}
kfree
(
buf
);
}
}
/**
/**
...
@@ -619,6 +612,9 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...
@@ -619,6 +612,9 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
lockdep_assert_held
(
&
mvm
->
mutex
);
lockdep_assert_held
(
&
mvm
->
mutex
);
if
(
mvmvif
->
low_latency
==
value
)
return
0
;
mvmvif
->
low_latency
=
value
;
mvmvif
->
low_latency
=
value
;
res
=
iwl_mvm_update_quotas
(
mvm
,
NULL
);
res
=
iwl_mvm_update_quotas
(
mvm
,
NULL
);
...
@@ -629,3 +625,22 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...
@@ -629,3 +625,22 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return
iwl_mvm_power_update_mac
(
mvm
,
vif
);
return
iwl_mvm_power_update_mac
(
mvm
,
vif
);
}
}
static
void
iwl_mvm_ll_iter
(
void
*
_data
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
)
{
bool
*
result
=
_data
;
if
(
iwl_mvm_vif_low_latency
(
iwl_mvm_vif_from_mac80211
(
vif
)))
*
result
=
true
;
}
bool
iwl_mvm_low_latency
(
struct
iwl_mvm
*
mvm
)
{
bool
result
=
false
;
ieee80211_iterate_active_interfaces_atomic
(
mvm
->
hw
,
IEEE80211_IFACE_ITER_NORMAL
,
iwl_mvm_ll_iter
,
&
result
);
return
result
;
}
drivers/net/wireless/iwlwifi/pcie/drv.c
浏览文件 @
aa4a6250
...
@@ -447,7 +447,8 @@ static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev)
...
@@ -447,7 +447,8 @@ static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev)
pxsx_handle
=
ACPI_HANDLE
(
&
pdev
->
dev
);
pxsx_handle
=
ACPI_HANDLE
(
&
pdev
->
dev
);
if
(
!
pxsx_handle
)
{
if
(
!
pxsx_handle
)
{
IWL_ERR
(
trans
,
"Could not retrieve root port ACPI handle"
);
IWL_DEBUG_INFO
(
trans
,
"Could not retrieve root port ACPI handle"
);
return
;
return
;
}
}
...
@@ -559,7 +560,7 @@ static int iwl_pci_resume(struct device *device)
...
@@ -559,7 +560,7 @@ static int iwl_pci_resume(struct device *device)
iwl_enable_rfkill_int
(
trans
);
iwl_enable_rfkill_int
(
trans
);
hw_rfkill
=
iwl_is_rfkill_set
(
trans
);
hw_rfkill
=
iwl_is_rfkill_set
(
trans
);
iwl_
op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
iwl_
trans_pcie_rf_kill
(
trans
,
hw_rfkill
);
return
0
;
return
0
;
}
}
...
...
drivers/net/wireless/iwlwifi/pcie/internal.h
浏览文件 @
aa4a6250
...
@@ -488,4 +488,6 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
...
@@ -488,4 +488,6 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
__iwl_trans_pcie_set_bits_mask
(
trans
,
reg
,
mask
,
mask
);
__iwl_trans_pcie_set_bits_mask
(
trans
,
reg
,
mask
,
mask
);
}
}
void
iwl_trans_pcie_rf_kill
(
struct
iwl_trans
*
trans
,
bool
state
);
#endif
/* __iwl_trans_int_pcie_h__ */
#endif
/* __iwl_trans_int_pcie_h__ */
drivers/net/wireless/iwlwifi/pcie/rx.c
浏览文件 @
aa4a6250
...
@@ -994,7 +994,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
...
@@ -994,7 +994,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
isr_stats
->
rfkill
++
;
isr_stats
->
rfkill
++
;
iwl_
op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
iwl_
trans_pcie_rf_kill
(
trans
,
hw_rfkill
);
if
(
hw_rfkill
)
{
if
(
hw_rfkill
)
{
set_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
set_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
if
(
test_and_clear_bit
(
STATUS_SYNC_HCMD_ACTIVE
,
if
(
test_and_clear_bit
(
STATUS_SYNC_HCMD_ACTIVE
,
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
浏览文件 @
aa4a6250
...
@@ -75,6 +75,20 @@
...
@@ -75,6 +75,20 @@
#include "iwl-agn-hw.h"
#include "iwl-agn-hw.h"
#include "internal.h"
#include "internal.h"
static
u32
iwl_trans_pcie_read_shr
(
struct
iwl_trans
*
trans
,
u32
reg
)
{
iwl_write32
(
trans
,
HEEP_CTRL_WRD_PCIEX_CTRL_REG
,
((
reg
&
0x0000ffff
)
|
(
2
<<
28
)));
return
iwl_read32
(
trans
,
HEEP_CTRL_WRD_PCIEX_DATA_REG
);
}
static
void
iwl_trans_pcie_write_shr
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
val
)
{
iwl_write32
(
trans
,
HEEP_CTRL_WRD_PCIEX_DATA_REG
,
val
);
iwl_write32
(
trans
,
HEEP_CTRL_WRD_PCIEX_CTRL_REG
,
((
reg
&
0x0000ffff
)
|
(
3
<<
28
)));
}
static
void
iwl_pcie_set_pwr
(
struct
iwl_trans
*
trans
,
bool
vaux
)
static
void
iwl_pcie_set_pwr
(
struct
iwl_trans
*
trans
,
bool
vaux
)
{
{
if
(
vaux
&&
pci_pme_capable
(
to_pci_dev
(
trans
->
dev
),
PCI_D3cold
))
if
(
vaux
&&
pci_pme_capable
(
to_pci_dev
(
trans
->
dev
),
PCI_D3cold
))
...
@@ -229,6 +243,116 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
...
@@ -229,6 +243,116 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
return
ret
;
return
ret
;
}
}
/*
* Enable LP XTAL to avoid HW bug where device may consume much power if
* FW is not loaded after device reset. LP XTAL is disabled by default
* after device HW reset. Do it only if XTAL is fed by internal source.
* Configure device's "persistence" mode to avoid resetting XTAL again when
* SHRD_HW_RST occurs in S3.
*/
static
void
iwl_pcie_apm_lp_xtal_enable
(
struct
iwl_trans
*
trans
)
{
int
ret
;
u32
apmg_gp1_reg
;
u32
apmg_xtal_cfg_reg
;
u32
dl_cfg_reg
;
/* Force XTAL ON */
__iwl_trans_pcie_set_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_XTAL_ON
);
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
iwl_set_bit
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_SW_RESET
);
udelay
(
10
);
/*
* Set "initialization complete" bit to move adapter from
* D0U* --> D0A* (powered-up active) state.
*/
iwl_set_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_INIT_DONE
);
/*
* Wait for clock stabilization; once stabilized, access to
* device-internal resources is possible.
*/
ret
=
iwl_poll_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
,
25000
);
if
(
WARN_ON
(
ret
<
0
))
{
IWL_ERR
(
trans
,
"Access time out - failed to enable LP XTAL
\n
"
);
/* Release XTAL ON request */
__iwl_trans_pcie_clear_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_XTAL_ON
);
return
;
}
/*
* Clear "disable persistence" to avoid LP XTAL resetting when
* SHRD_HW_RST is applied in S3.
*/
iwl_clear_bits_prph
(
trans
,
APMG_PCIDEV_STT_REG
,
APMG_PCIDEV_STT_VAL_PERSIST_DIS
);
/*
* Force APMG XTAL to be active to prevent its disabling by HW
* caused by APMG idle state.
*/
apmg_xtal_cfg_reg
=
iwl_trans_pcie_read_shr
(
trans
,
SHR_APMG_XTAL_CFG_REG
);
iwl_trans_pcie_write_shr
(
trans
,
SHR_APMG_XTAL_CFG_REG
,
apmg_xtal_cfg_reg
|
SHR_APMG_XTAL_CFG_XTAL_ON_REQ
);
/*
* Reset entire device again - do controller reset (results in
* SHRD_HW_RST). Turn MAC off before proceeding.
*/
iwl_set_bit
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_SW_RESET
);
udelay
(
10
);
/* Enable LP XTAL by indirect access through CSR */
apmg_gp1_reg
=
iwl_trans_pcie_read_shr
(
trans
,
SHR_APMG_GP1_REG
);
iwl_trans_pcie_write_shr
(
trans
,
SHR_APMG_GP1_REG
,
apmg_gp1_reg
|
SHR_APMG_GP1_WF_XTAL_LP_EN
|
SHR_APMG_GP1_CHICKEN_BIT_SELECT
);
/* Clear delay line clock power up */
dl_cfg_reg
=
iwl_trans_pcie_read_shr
(
trans
,
SHR_APMG_DL_CFG_REG
);
iwl_trans_pcie_write_shr
(
trans
,
SHR_APMG_DL_CFG_REG
,
dl_cfg_reg
&
~
SHR_APMG_DL_CFG_DL_CLOCK_POWER_UP
);
/*
* Enable persistence mode to avoid LP XTAL resetting when
* SHRD_HW_RST is applied in S3.
*/
iwl_set_bit
(
trans
,
CSR_HW_IF_CONFIG_REG
,
CSR_HW_IF_CONFIG_REG_PERSIST_MODE
);
/*
* Clear "initialization complete" bit to move adapter from
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
iwl_clear_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_INIT_DONE
);
/* Activates XTAL resources monitor */
__iwl_trans_pcie_set_bit
(
trans
,
CSR_MONITOR_CFG_REG
,
CSR_MONITOR_XTAL_RESOURCES
);
/* Release XTAL ON request */
__iwl_trans_pcie_clear_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_XTAL_ON
);
udelay
(
10
);
/* Release APMG XTAL */
iwl_trans_pcie_write_shr
(
trans
,
SHR_APMG_XTAL_CFG_REG
,
apmg_xtal_cfg_reg
&
~
SHR_APMG_XTAL_CFG_XTAL_ON_REQ
);
}
static
int
iwl_pcie_apm_stop_master
(
struct
iwl_trans
*
trans
)
static
int
iwl_pcie_apm_stop_master
(
struct
iwl_trans
*
trans
)
{
{
int
ret
=
0
;
int
ret
=
0
;
...
@@ -256,6 +380,11 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans)
...
@@ -256,6 +380,11 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans)
/* Stop device's DMA activity */
/* Stop device's DMA activity */
iwl_pcie_apm_stop_master
(
trans
);
iwl_pcie_apm_stop_master
(
trans
);
if
(
trans
->
cfg
->
lp_xtal_workaround
)
{
iwl_pcie_apm_lp_xtal_enable
(
trans
);
return
;
}
/* Reset the entire device */
/* Reset the entire device */
iwl_set_bit
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_SW_RESET
);
iwl_set_bit
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_SW_RESET
);
...
@@ -641,7 +770,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
...
@@ -641,7 +770,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
set_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
set_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
else
else
clear_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
clear_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
iwl_
op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
iwl_
trans_pcie_rf_kill
(
trans
,
hw_rfkill
);
if
(
hw_rfkill
&&
!
run_in_rfkill
)
if
(
hw_rfkill
&&
!
run_in_rfkill
)
return
-
ERFKILL
;
return
-
ERFKILL
;
...
@@ -756,7 +885,13 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
...
@@ -756,7 +885,13 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
else
else
clear_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
clear_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
if
(
hw_rfkill
!=
was_hw_rfkill
)
if
(
hw_rfkill
!=
was_hw_rfkill
)
iwl_op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
iwl_trans_pcie_rf_kill
(
trans
,
hw_rfkill
);
}
void
iwl_trans_pcie_rf_kill
(
struct
iwl_trans
*
trans
,
bool
state
)
{
if
(
iwl_op_mode_hw_rf_kill
(
trans
->
op_mode
,
state
))
iwl_trans_pcie_stop_device
(
trans
);
}
}
static
void
iwl_trans_pcie_d3_suspend
(
struct
iwl_trans
*
trans
,
bool
test
)
static
void
iwl_trans_pcie_d3_suspend
(
struct
iwl_trans
*
trans
,
bool
test
)
...
@@ -865,7 +1000,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
...
@@ -865,7 +1000,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
set_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
set_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
else
else
clear_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
clear_bit
(
STATUS_RFKILL
,
&
trans
->
status
);
iwl_
op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
iwl_
trans_pcie_rf_kill
(
trans
,
hw_rfkill
);
return
0
;
return
0
;
}
}
...
@@ -1208,6 +1343,7 @@ static const char *get_csr_string(int cmd)
...
@@ -1208,6 +1343,7 @@ static const char *get_csr_string(int cmd)
IWL_CMD
(
CSR_GIO_CHICKEN_BITS
);
IWL_CMD
(
CSR_GIO_CHICKEN_BITS
);
IWL_CMD
(
CSR_ANA_PLL_CFG
);
IWL_CMD
(
CSR_ANA_PLL_CFG
);
IWL_CMD
(
CSR_HW_REV_WA_REG
);
IWL_CMD
(
CSR_HW_REV_WA_REG
);
IWL_CMD
(
CSR_MONITOR_STATUS_REG
);
IWL_CMD
(
CSR_DBG_HPET_MEM_REG
);
IWL_CMD
(
CSR_DBG_HPET_MEM_REG
);
default:
default:
return
"UNKNOWN"
;
return
"UNKNOWN"
;
...
@@ -1240,6 +1376,7 @@ void iwl_pcie_dump_csr(struct iwl_trans *trans)
...
@@ -1240,6 +1376,7 @@ void iwl_pcie_dump_csr(struct iwl_trans *trans)
CSR_DRAM_INT_TBL_REG
,
CSR_DRAM_INT_TBL_REG
,
CSR_GIO_CHICKEN_BITS
,
CSR_GIO_CHICKEN_BITS
,
CSR_ANA_PLL_CFG
,
CSR_ANA_PLL_CFG
,
CSR_MONITOR_STATUS_REG
,
CSR_HW_REV_WA_REG
,
CSR_HW_REV_WA_REG
,
CSR_DBG_HPET_MEM_REG
CSR_DBG_HPET_MEM_REG
};
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录