Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
d3d3e001
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
d3d3e001
编写于
9月 26, 2014
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
上级
7a0a260a
48849a41
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
573 addition
and
160 deletion
+573
-160
drivers/net/wireless/iwlwifi/iwl-8000.c
drivers/net/wireless/iwlwifi/iwl-8000.c
+1
-1
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-drv.c
+18
-0
drivers/net/wireless/iwlwifi/iwl-fw.h
drivers/net/wireless/iwlwifi/iwl-fw.h
+16
-1
drivers/net/wireless/iwlwifi/mvm/constants.h
drivers/net/wireless/iwlwifi/mvm/constants.h
+2
-1
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
+25
-0
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+3
-0
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+2
-0
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
+60
-0
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+9
-11
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+26
-11
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/mvm.h
+43
-0
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/ops.c
+2
-1
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rs.c
+157
-83
drivers/net/wireless/iwlwifi/mvm/rs.h
drivers/net/wireless/iwlwifi/mvm/rs.h
+4
-0
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/rx.c
+24
-17
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/scan.c
+66
-13
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/sta.c
+14
-6
drivers/net/wireless/iwlwifi/mvm/sta.h
drivers/net/wireless/iwlwifi/mvm/sta.h
+2
-0
drivers/net/wireless/iwlwifi/mvm/tt.c
drivers/net/wireless/iwlwifi/mvm/tt.c
+1
-1
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/tx.c
+47
-13
drivers/net/wireless/iwlwifi/mvm/utils.c
drivers/net/wireless/iwlwifi/mvm/utils.c
+46
-0
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/drv.c
+4
-0
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+1
-1
未找到文件。
drivers/net/wireless/iwlwifi/iwl-8000.c
浏览文件 @
d3d3e001
...
...
@@ -81,7 +81,7 @@
#define IWL8000_NVM_VERSION 0x0a1d
#define IWL8000_TX_POWER_VERSION 0xffff
/* meaningless */
#define IWL8000_FW_PRE "iwlwifi-8000
-
"
#define IWL8000_FW_PRE "iwlwifi-8000"
#define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE __stringify(api) ".ucode"
#define NVM_HW_SECTION_NUM_FAMILY_8000 10
...
...
drivers/net/wireless/iwlwifi/iwl-drv.c
浏览文件 @
d3d3e001
...
...
@@ -69,6 +69,7 @@
#include <linux/vmalloc.h>
#include "iwl-drv.h"
#include "iwl-csr.h"
#include "iwl-debug.h"
#include "iwl-trans.h"
#include "iwl-op-mode.h"
...
...
@@ -244,6 +245,23 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
snprintf
(
drv
->
firmware_name
,
sizeof
(
drv
->
firmware_name
),
"%s%s.ucode"
,
name_pre
,
tag
);
/*
* Starting 8000B - FW name format has changed. This overwrites the
* previous name and uses the new format.
*/
if
(
drv
->
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_8000
)
{
char
rev_step
[
2
]
=
{
'A'
+
CSR_HW_REV_STEP
(
drv
->
trans
->
hw_rev
),
0
};
/* A-step doesn't have an indication */
if
(
CSR_HW_REV_STEP
(
drv
->
trans
->
hw_rev
)
==
SILICON_A_STEP
)
rev_step
[
0
]
=
0
;
snprintf
(
drv
->
firmware_name
,
sizeof
(
drv
->
firmware_name
),
"%s%s-%s.ucode"
,
name_pre
,
rev_step
,
tag
);
}
IWL_DEBUG_INFO
(
drv
,
"attempting to load firmware %s'%s'
\n
"
,
(
drv
->
fw_index
==
UCODE_EXPERIMENTAL_INDEX
)
?
"EXPERIMENTAL "
:
""
,
...
...
drivers/net/wireless/iwlwifi/iwl-fw.h
浏览文件 @
d3d3e001
...
...
@@ -145,9 +145,24 @@ enum iwl_ucode_tlv_api {
/**
* enum iwl_ucode_tlv_capa - ucode capabilities
* @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
* @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
* tx power value into TPC Report action frame and Link Measurement Report
* action frame
* @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports adding DS params
* element in probe requests.
* @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in
* probe requests.
* @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
* @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
* which also implies support for the scheduler configuration command
*/
enum
iwl_ucode_tlv_capa
{
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT
=
BIT
(
0
),
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT
=
BIT
(
0
),
IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT
=
BIT
(
8
),
IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT
=
BIT
(
9
),
IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT
=
BIT
(
10
),
IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT
=
BIT
(
11
),
IWL_UCODE_TLV_CAPA_DQA_SUPPORT
=
BIT
(
12
),
};
/* The default calibrate table size if not specified by firmware file */
...
...
drivers/net/wireless/iwlwifi/mvm/constants.h
浏览文件 @
d3d3e001
...
...
@@ -90,9 +90,10 @@
#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62
#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65
#define IWL_MVM_BT_COEX_SYNC2SCO 1
#define IWL_MVM_BT_COEX_CORUNNING
1
#define IWL_MVM_BT_COEX_CORUNNING
0
#define IWL_MVM_BT_COEX_MPLUT 1
#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
#define IWL_MVM_QUOTA_THRESHOLD 8
#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
#endif
/* __MVM_CONSTANTS_H */
drivers/net/wireless/iwlwifi/mvm/debugfs.c
浏览文件 @
d3d3e001
...
...
@@ -326,6 +326,29 @@ static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
return
count
;
}
static
ssize_t
iwl_dbgfs_nic_temp_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
struct
iwl_mvm
*
mvm
=
file
->
private_data
;
char
buf
[
16
];
int
pos
,
temp
;
if
(
!
mvm
->
ucode_loaded
)
return
-
EIO
;
mutex_lock
(
&
mvm
->
mutex
);
temp
=
iwl_mvm_get_temp
(
mvm
);
mutex_unlock
(
&
mvm
->
mutex
);
if
(
temp
<
0
)
return
temp
;
pos
=
scnprintf
(
buf
,
sizeof
(
buf
),
"%d
\n
"
,
temp
);
return
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
pos
);
}
static
ssize_t
iwl_dbgfs_stations_read
(
struct
file
*
file
,
char
__user
*
user_buf
,
size_t
count
,
loff_t
*
ppos
)
{
...
...
@@ -1378,6 +1401,7 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
MVM_DEBUGFS_WRITE_FILE_OPS
(
sta_drain
,
8
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
sram
,
64
);
MVM_DEBUGFS_READ_WRITE_FILE_OPS
(
set_nic_temperature
,
64
);
MVM_DEBUGFS_READ_FILE_OPS
(
nic_temp
);
MVM_DEBUGFS_READ_FILE_OPS
(
stations
);
MVM_DEBUGFS_READ_FILE_OPS
(
bt_notif
);
MVM_DEBUGFS_READ_FILE_OPS
(
bt_cmd
);
...
...
@@ -1420,6 +1444,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE
(
sram
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
set_nic_temperature
,
mvm
->
debugfs_dir
,
S_IWUSR
|
S_IRUSR
);
MVM_DEBUGFS_ADD_FILE
(
nic_temp
,
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
);
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
浏览文件 @
d3d3e001
...
...
@@ -670,6 +670,8 @@ struct iwl_scan_channel_opt {
* @IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE: send iteration complete notification
* @IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS multiple SSID matching
* @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented
* @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report
* and DS parameter set IEs into probe requests.
*/
enum
iwl_mvm_lmac_scan_flags
{
IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL
=
BIT
(
0
),
...
...
@@ -678,6 +680,7 @@ enum iwl_mvm_lmac_scan_flags {
IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE
=
BIT
(
3
),
IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS
=
BIT
(
4
),
IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED
=
BIT
(
5
),
IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED
=
BIT
(
6
),
};
enum
iwl_scan_priority
{
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
浏览文件 @
d3d3e001
...
...
@@ -66,6 +66,7 @@
/**
* enum iwl_tx_flags - bitmasks for tx_flags in TX command
* @TX_CMD_FLG_PROT_REQUIRE: use RTS or CTS-to-self to protect the frame
* @TX_CMD_FLG_WRITE_TX_POWER: update current tx power value in the mgmt frame
* @TX_CMD_FLG_ACK: expect ACK from receiving station
* @TX_CMD_FLG_STA_RATE: use RS table with initial index from the TX command.
* Otherwise, use rate_n_flags from the TX command
...
...
@@ -97,6 +98,7 @@
*/
enum
iwl_tx_flags
{
TX_CMD_FLG_PROT_REQUIRE
=
BIT
(
0
),
TX_CMD_FLG_WRITE_TX_POWER
=
BIT
(
1
),
TX_CMD_FLG_ACK
=
BIT
(
3
),
TX_CMD_FLG_STA_RATE
=
BIT
(
4
),
TX_CMD_FLG_BAR
=
BIT
(
6
),
...
...
drivers/net/wireless/iwlwifi/mvm/fw-api.h
浏览文件 @
d3d3e001
...
...
@@ -116,6 +116,9 @@ enum {
TXPATH_FLUSH
=
0x1e
,
MGMT_MCAST_KEY
=
0x1f
,
/* scheduler config */
SCD_QUEUE_CFG
=
0x1d
,
/* global key */
WEP_KEY
=
0x20
,
...
...
@@ -1650,4 +1653,61 @@ struct iwl_dts_measurement_notif {
__le32
voltage
;
}
__packed
;
/* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */
/**
* enum iwl_scd_control - scheduler config command control flags
* @IWL_SCD_CONTROL_RM_TID: remove TID from this queue
* @IWL_SCD_CONTROL_SET_SSN: use the SSN and program it into HW
*/
enum
iwl_scd_control
{
IWL_SCD_CONTROL_RM_TID
=
BIT
(
4
),
IWL_SCD_CONTROL_SET_SSN
=
BIT
(
5
),
};
/**
* enum iwl_scd_flags - scheduler config command flags
* @IWL_SCD_FLAGS_SHARE_TID: multiple TIDs map to this queue
* @IWL_SCD_FLAGS_SHARE_RA: multiple RAs map to this queue
* @IWL_SCD_FLAGS_DQA_ENABLED: DQA is enabled
*/
enum
iwl_scd_flags
{
IWL_SCD_FLAGS_SHARE_TID
=
BIT
(
0
),
IWL_SCD_FLAGS_SHARE_RA
=
BIT
(
1
),
IWL_SCD_FLAGS_DQA_ENABLED
=
BIT
(
2
),
};
#define IWL_SCDQ_INVALID_STA 0xff
/**
* struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command
* @token: dialog token addba - unused legacy
* @sta_id: station id 4-bit
* @tid: TID 0..7
* @scd_queue: TFD queue num 0 .. 31
* @enable: 1 queue enable, 0 queue disable
* @aggregate: 1 aggregated queue, 0 otherwise
* @tx_fifo: tx fifo num 0..7
* @window: up to 64
* @ssn: starting seq num 12-bit
* @control: command control flags
* @flags: flags - see &enum iwl_scd_flags
*
* Note that every time the command is sent, all parameters must
* be filled with the exception of
* - the SSN, which is only used with @IWL_SCD_CONTROL_SET_SSN
* - the window, which is only relevant when starting aggregation
*/
struct
iwl_scd_txq_cfg_cmd
{
u8
token
;
u8
sta_id
;
u8
tid
;
u8
scd_queue
;
u8
enable
;
u8
aggregate
;
u8
tx_fifo
;
u8
window
;
__le16
ssn
;
u8
control
;
u8
flags
;
}
__packed
;
#endif
/* __fw_api_h__ */
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
浏览文件 @
d3d3e001
...
...
@@ -427,17 +427,17 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
switch
(
vif
->
type
)
{
case
NL80211_IFTYPE_P2P_DEVICE
:
iwl_
trans_ac_txq_enable
(
mvm
->
trans
,
IWL_MVM_OFFCHANNEL_QUEUE
,
IWL_MVM_TX_FIFO_VO
);
iwl_
mvm_enable_ac_txq
(
mvm
,
IWL_MVM_OFFCHANNEL_QUEUE
,
IWL_MVM_TX_FIFO_VO
);
break
;
case
NL80211_IFTYPE_AP
:
iwl_
trans_ac_txq_enable
(
mvm
->
trans
,
vif
->
cab_queue
,
IWL_MVM_TX_FIFO_MCAST
);
iwl_
mvm_enable_ac_txq
(
mvm
,
vif
->
cab_queue
,
IWL_MVM_TX_FIFO_MCAST
);
/* fall through */
default:
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
iwl_
trans_ac_txq_enable
(
mvm
->
trans
,
vif
->
hw_queue
[
ac
],
iwl_mvm_ac_to_tx_fifo
[
ac
]);
iwl_
mvm_enable_ac_txq
(
mvm
,
vif
->
hw_queue
[
ac
],
iwl_mvm_ac_to_tx_fifo
[
ac
]);
break
;
}
...
...
@@ -452,16 +452,14 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
switch
(
vif
->
type
)
{
case
NL80211_IFTYPE_P2P_DEVICE
:
iwl_trans_txq_disable
(
mvm
->
trans
,
IWL_MVM_OFFCHANNEL_QUEUE
,
true
);
iwl_mvm_disable_txq
(
mvm
,
IWL_MVM_OFFCHANNEL_QUEUE
);
break
;
case
NL80211_IFTYPE_AP
:
iwl_
trans_txq_disable
(
mvm
->
trans
,
vif
->
cab_queue
,
tr
ue
);
iwl_
mvm_disable_txq
(
mvm
,
vif
->
cab_que
ue
);
/* fall through */
default:
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
iwl_trans_txq_disable
(
mvm
->
trans
,
vif
->
hw_queue
[
ac
],
true
);
iwl_mvm_disable_txq
(
mvm
,
vif
->
hw_queue
[
ac
]);
}
}
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
浏览文件 @
d3d3e001
...
...
@@ -279,14 +279,6 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
}
}
static
int
iwl_mvm_max_scan_ie_len
(
struct
iwl_mvm
*
mvm
)
{
/* we create the 802.11 header and SSID element */
if
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID
)
return
mvm
->
fw
->
ucode_capa
.
max_probe_length
-
24
-
2
;
return
mvm
->
fw
->
ucode_capa
.
max_probe_length
-
24
-
34
;
}
int
iwl_mvm_mac_setup_register
(
struct
iwl_mvm
*
mvm
)
{
struct
ieee80211_hw
*
hw
=
mvm
->
hw
;
...
...
@@ -303,7 +295,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IEEE80211_HW_AMPDU_AGGREGATION
|
IEEE80211_HW_TIMING_BEACON_ONLY
|
IEEE80211_HW_CONNECTION_MONITOR
|
IEEE80211_HW_CHANCTX_STA_CSA
;
IEEE80211_HW_CHANCTX_STA_CSA
|
IEEE80211_HW_SUPPORTS_CLONED_SKBS
;
hw
->
queues
=
mvm
->
first_agg_queue
;
hw
->
offchannel_tx_hw_queue
=
IWL_MVM_OFFCHANNEL_QUEUE
;
...
...
@@ -378,7 +371,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
iwl_mvm_reset_phy_ctxts
(
mvm
);
hw
->
wiphy
->
max_scan_ie_len
=
iwl_mvm_max_scan_ie_len
(
mvm
);
hw
->
wiphy
->
max_scan_ie_len
=
iwl_mvm_max_scan_ie_len
(
mvm
,
false
);
hw
->
wiphy
->
max_scan_ssids
=
PROBE_OPTION_MAX
;
...
...
@@ -411,6 +404,22 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
NL80211_FEATURE_DYNAMIC_SMPS
|
NL80211_FEATURE_STATIC_SMPS
;
if
(
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT
)
hw
->
wiphy
->
features
|=
NL80211_FEATURE_TX_POWER_INSERTION
;
if
(
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT
)
hw
->
wiphy
->
features
|=
NL80211_FEATURE_QUIET
;
if
(
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT
)
hw
->
wiphy
->
features
|=
NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES
;
if
(
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT
)
hw
->
wiphy
->
features
|=
NL80211_FEATURE_WFA_TPC_IE_IN_PROBES
;
mvm
->
rts_threshold
=
IEEE80211_MAX_RTS_THRESHOLD
;
/* currently FW API supports only one optional cipher scheme */
...
...
@@ -2135,7 +2144,13 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
mutex_lock
(
&
mvm
->
mutex
);
if
(
!
iwl_mvm_is_idle
(
mvm
))
{
/* Newest FW fixes sched scan while connected on another interface */
if
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_LMAC_SCAN
)
{
if
(
!
vif
->
bss_conf
.
idle
)
{
ret
=
-
EBUSY
;
goto
out
;
}
}
else
if
(
!
iwl_mvm_is_idle
(
mvm
))
{
ret
=
-
EBUSY
;
goto
out
;
}
...
...
drivers/net/wireless/iwlwifi/mvm/mvm.h
浏览文件 @
d3d3e001
...
...
@@ -779,6 +779,11 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
(
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT
);
}
static
inline
bool
iwl_mvm_is_dqa_supported
(
struct
iwl_mvm
*
mvm
)
{
return
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_DQA_SUPPORT
;
}
extern
const
u8
iwl_mvm_ac_to_tx_fifo
[];
struct
iwl_rate_info
{
...
...
@@ -930,6 +935,7 @@ int iwl_mvm_rx_scan_response(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
);
int
iwl_mvm_cancel_scan
(
struct
iwl_mvm
*
mvm
);
int
iwl_mvm_max_scan_ie_len
(
struct
iwl_mvm
*
mvm
,
bool
is_sched_scan
);
/* Scheduled scan */
int
iwl_mvm_rx_scan_offload_complete_notif
(
struct
iwl_mvm
*
mvm
,
...
...
@@ -984,6 +990,9 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
struct
iwl_mvm_frame_stats
*
stats
,
u32
rate
,
bool
agg
);
int
rs_pretty_print_rate
(
char
*
buf
,
const
u32
rate
);
void
rs_update_last_rssi
(
struct
iwl_mvm
*
mvm
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_rx_status
*
rx_status
);
/* power management */
int
iwl_mvm_power_update_device
(
struct
iwl_mvm
*
mvm
);
...
...
@@ -1141,6 +1150,39 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
return
mvmvif
->
low_latency
;
}
/* hw scheduler queue config */
void
iwl_mvm_enable_txq
(
struct
iwl_mvm
*
mvm
,
int
queue
,
u16
ssn
,
const
struct
iwl_trans_txq_scd_cfg
*
cfg
);
void
iwl_mvm_disable_txq
(
struct
iwl_mvm
*
mvm
,
int
queue
);
static
inline
void
iwl_mvm_enable_ac_txq
(
struct
iwl_mvm
*
mvm
,
int
queue
,
u8
fifo
)
{
struct
iwl_trans_txq_scd_cfg
cfg
=
{
.
fifo
=
fifo
,
.
tid
=
IWL_MAX_TID_COUNT
,
.
aggregate
=
false
,
.
frame_limit
=
IWL_FRAME_LIMIT
,
};
iwl_mvm_enable_txq
(
mvm
,
queue
,
0
,
&
cfg
);
}
static
inline
void
iwl_mvm_enable_agg_txq
(
struct
iwl_mvm
*
mvm
,
int
queue
,
int
fifo
,
int
sta_id
,
int
tid
,
int
frame_limit
,
u16
ssn
)
{
struct
iwl_trans_txq_scd_cfg
cfg
=
{
.
fifo
=
fifo
,
.
sta_id
=
sta_id
,
.
tid
=
tid
,
.
frame_limit
=
frame_limit
,
.
aggregate
=
true
,
};
iwl_mvm_enable_txq
(
mvm
,
queue
,
ssn
,
&
cfg
);
}
/* Assoc status */
bool
iwl_mvm_is_idle
(
struct
iwl_mvm
*
mvm
);
...
...
@@ -1150,6 +1192,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
void
iwl_mvm_tt_initialize
(
struct
iwl_mvm
*
mvm
,
u32
min_backoff
);
void
iwl_mvm_tt_exit
(
struct
iwl_mvm
*
mvm
);
void
iwl_mvm_set_hw_ctkill_state
(
struct
iwl_mvm
*
mvm
,
bool
state
);
int
iwl_mvm_get_temp
(
struct
iwl_mvm
*
mvm
);
/* smart fifo */
int
iwl_mvm_sf_update
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
...
...
drivers/net/wireless/iwlwifi/mvm/ops.c
浏览文件 @
d3d3e001
...
...
@@ -342,6 +342,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD
(
BT_COEX_UPDATE_REDUCED_TXP
),
CMD
(
PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION
),
CMD
(
ANTENNA_COUPLING_NOTIFICATION
),
CMD
(
SCD_QUEUE_CFG
),
};
#undef CMD
...
...
@@ -421,7 +422,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm
->
first_agg_queue
=
12
;
}
mvm
->
sf_state
=
SF_UNINIT
;
mvm
->
low_latency_agg_frame_limit
=
1
;
mvm
->
low_latency_agg_frame_limit
=
6
;
mutex_init
(
&
mvm
->
mutex
);
mutex_init
(
&
mvm
->
d0i3_suspend_mutex
);
...
...
drivers/net/wireless/iwlwifi/mvm/rs.c
浏览文件 @
d3d3e001
...
...
@@ -377,9 +377,9 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
}
static
void
rs_rate_scale_perform
(
struct
iwl_mvm
*
mvm
,
struct
sk_buff
*
skb
,
struct
ieee80211_sta
*
sta
,
struct
iwl_lq_sta
*
lq_sta
);
struct
ieee80211_sta
*
sta
,
struct
iwl_lq_sta
*
lq_
sta
,
int
tid
);
static
void
rs_fill_lq_cmd
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
,
struct
iwl_lq_sta
*
lq_sta
,
...
...
@@ -1007,27 +1007,35 @@ static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
return
RATE_MCS_CHAN_WIDTH_20
;
}
/*
* mac80211 sends us Tx status
*/
static
void
rs_tx_status
(
void
*
mvm_r
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
)
static
u8
rs_get_tid
(
struct
ieee80211_hdr
*
hdr
)
{
u8
tid
=
IWL_MAX_TID_COUNT
;
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
))
{
u8
*
qc
=
ieee80211_get_qos_ctl
(
hdr
);
tid
=
qc
[
0
]
&
0xf
;
}
if
(
unlikely
(
tid
>
IWL_MAX_TID_COUNT
))
tid
=
IWL_MAX_TID_COUNT
;
return
tid
;
}
void
iwl_mvm_rs_tx_status
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
,
int
tid
,
struct
ieee80211_tx_info
*
info
)
{
int
legacy_success
;
int
retries
;
int
mac_index
,
i
;
struct
iwl_lq_sta
*
lq_sta
=
priv_sta
;
struct
iwl_lq_cmd
*
table
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
iwl_op_mode
*
op_mode
=
(
struct
iwl_op_mode
*
)
mvm_r
;
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
enum
mac80211_rate_control_flags
mac_flags
;
u32
ucode_rate
;
struct
rs_rate
rate
;
struct
iwl_scale_tbl_info
*
curr_tbl
,
*
other_tbl
,
*
tmp_tbl
;
u8
reduced_txp
=
(
uintptr_t
)
info
->
status
.
status_driver_data
[
0
];
struct
iwl_mvm_sta
*
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
struct
iwl_lq_sta
*
lq_sta
=
&
mvmsta
->
lq_sta
;
/* Treat uninitialized rate scaling data same as non-existing. */
if
(
!
lq_sta
)
{
...
...
@@ -1045,10 +1053,6 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
return
;
}
#endif
if
(
!
ieee80211_is_data
(
hdr
->
frame_control
)
||
info
->
flags
&
IEEE80211_TX_CTL_NO_ACK
)
return
;
/* This packet was aggregated but doesn't carry status info */
if
((
info
->
flags
&
IEEE80211_TX_CTL_AMPDU
)
&&
!
(
info
->
flags
&
IEEE80211_TX_STAT_AMPDU
))
...
...
@@ -1094,7 +1098,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
for
(
tid
=
0
;
tid
<
IWL_MAX_TID_COUNT
;
tid
++
)
ieee80211_stop_tx_ba_session
(
sta
,
tid
);
iwl_mvm_rs_rate_init
(
mvm
,
sta
,
sband
->
band
,
false
);
iwl_mvm_rs_rate_init
(
mvm
,
sta
,
info
->
band
,
false
);
return
;
}
lq_sta
->
last_tx
=
jiffies
;
...
...
@@ -1221,8 +1225,28 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
IWL_DEBUG_RATE
(
mvm
,
"reduced txpower: %d
\n
"
,
reduced_txp
);
done:
/* See if there's a better rate or modulation mode to try. */
if
(
sta
&&
sta
->
supp_rates
[
sband
->
band
])
rs_rate_scale_perform
(
mvm
,
skb
,
sta
,
lq_sta
);
if
(
sta
&&
sta
->
supp_rates
[
info
->
band
])
rs_rate_scale_perform
(
mvm
,
sta
,
lq_sta
,
tid
);
}
/*
* mac80211 sends us Tx status
*/
static
void
rs_mac80211_tx_status
(
void
*
mvm_r
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
)
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
iwl_op_mode
*
op_mode
=
(
struct
iwl_op_mode
*
)
mvm_r
;
struct
iwl_mvm
*
mvm
=
IWL_OP_MODE_GET_MVM
(
op_mode
);
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
if
(
!
ieee80211_is_data
(
hdr
->
frame_control
)
||
info
->
flags
&
IEEE80211_TX_CTL_NO_ACK
)
return
;
iwl_mvm_rs_tx_status
(
mvm
,
sta
,
rs_get_tid
(
hdr
),
info
);
}
/*
...
...
@@ -1493,22 +1517,6 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
iwl_mvm_send_lq_cmd
(
mvm
,
&
lq_sta
->
lq
,
false
);
}
static
u8
rs_get_tid
(
struct
iwl_lq_sta
*
lq_data
,
struct
ieee80211_hdr
*
hdr
)
{
u8
tid
=
IWL_MAX_TID_COUNT
;
if
(
ieee80211_is_data_qos
(
hdr
->
frame_control
))
{
u8
*
qc
=
ieee80211_get_qos_ctl
(
hdr
);
tid
=
qc
[
0
]
&
0xf
;
}
if
(
unlikely
(
tid
>
IWL_MAX_TID_COUNT
))
tid
=
IWL_MAX_TID_COUNT
;
return
tid
;
}
static
enum
rs_column
rs_get_next_column
(
struct
iwl_mvm
*
mvm
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_sta
*
sta
,
...
...
@@ -1947,12 +1955,10 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
* Do rate scaling and search for new modulation mode.
*/
static
void
rs_rate_scale_perform
(
struct
iwl_mvm
*
mvm
,
struct
sk_buff
*
skb
,
struct
ieee80211_sta
*
sta
,
struct
iwl_lq_sta
*
lq_sta
)
struct
iwl_lq_sta
*
lq_sta
,
int
tid
)
{
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
int
low
=
IWL_RATE_INVALID
;
int
high
=
IWL_RATE_INVALID
;
int
index
;
...
...
@@ -1969,29 +1975,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
u8
done_search
=
0
;
u16
high_low
;
s32
sr
;
u8
tid
=
IWL_MAX_TID_COUNT
;
u8
prev_agg
=
lq_sta
->
is_agg
;
struct
iwl_mvm_sta
*
sta_priv
=
(
void
*
)
sta
->
drv_priv
;
struct
iwl_mvm_tid_data
*
tid_data
;
struct
rs_rate
*
rate
;
/* Send management frames and NO_ACK data using lowest rate. */
/* TODO: this could probably be improved.. */
if
(
!
ieee80211_is_data
(
hdr
->
frame_control
)
||
info
->
flags
&
IEEE80211_TX_CTL_NO_ACK
)
return
;
tid
=
rs_get_tid
(
lq_sta
,
hdr
);
if
((
tid
!=
IWL_MAX_TID_COUNT
)
&&
(
lq_sta
->
tx_agg_tid_en
&
(
1
<<
tid
)))
{
tid_data
=
&
sta_priv
->
tid_data
[
tid
];
if
(
tid_data
->
state
==
IWL_AGG_OFF
)
lq_sta
->
is_agg
=
0
;
else
lq_sta
->
is_agg
=
1
;
}
else
{
lq_sta
->
is_agg
=
0
;
}
lq_sta
->
is_agg
=
!!
sta_priv
->
agg_tids
;
/*
* Select rate-scale / modulation-mode table to work with in
...
...
@@ -2288,6 +2277,110 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
lq_sta
->
last_txrate_idx
=
index
;
}
struct
rs_init_rate_info
{
s8
rssi
;
u8
rate_idx
;
};
static
const
struct
rs_init_rate_info
rs_init_rates_24ghz
[]
=
{
{
-
60
,
IWL_RATE_54M_INDEX
},
{
-
64
,
IWL_RATE_48M_INDEX
},
{
-
68
,
IWL_RATE_36M_INDEX
},
{
-
80
,
IWL_RATE_24M_INDEX
},
{
-
84
,
IWL_RATE_18M_INDEX
},
{
-
85
,
IWL_RATE_12M_INDEX
},
{
-
86
,
IWL_RATE_11M_INDEX
},
{
-
88
,
IWL_RATE_5M_INDEX
},
{
-
90
,
IWL_RATE_2M_INDEX
},
{
S8_MIN
,
IWL_RATE_1M_INDEX
},
};
static
const
struct
rs_init_rate_info
rs_init_rates_5ghz
[]
=
{
{
-
60
,
IWL_RATE_54M_INDEX
},
{
-
64
,
IWL_RATE_48M_INDEX
},
{
-
72
,
IWL_RATE_36M_INDEX
},
{
-
80
,
IWL_RATE_24M_INDEX
},
{
-
84
,
IWL_RATE_18M_INDEX
},
{
-
85
,
IWL_RATE_12M_INDEX
},
{
-
87
,
IWL_RATE_9M_INDEX
},
{
S8_MIN
,
IWL_RATE_6M_INDEX
},
};
/* Choose an initial legacy rate and antenna to use based on the RSSI
* of last Rx
*/
static
void
rs_get_initial_rate
(
struct
iwl_mvm
*
mvm
,
struct
iwl_lq_sta
*
lq_sta
,
enum
ieee80211_band
band
,
struct
rs_rate
*
rate
)
{
int
i
,
nentries
;
s8
best_rssi
=
S8_MIN
;
u8
best_ant
=
ANT_NONE
;
u8
valid_tx_ant
=
mvm
->
fw
->
valid_tx_ant
;
const
struct
rs_init_rate_info
*
initial_rates
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
lq_sta
->
pers
.
chain_signal
);
i
++
)
{
if
(
!
(
lq_sta
->
pers
.
chains
&
BIT
(
i
)))
continue
;
if
(
lq_sta
->
pers
.
chain_signal
[
i
]
>
best_rssi
)
{
best_rssi
=
lq_sta
->
pers
.
chain_signal
[
i
];
best_ant
=
BIT
(
i
);
}
}
IWL_DEBUG_RATE
(
mvm
,
"Best ANT: %s Best RSSI: %d
\n
"
,
rs_pretty_ant
(
best_ant
),
best_rssi
);
if
(
best_ant
!=
ANT_A
&&
best_ant
!=
ANT_B
)
rate
->
ant
=
first_antenna
(
valid_tx_ant
);
else
rate
->
ant
=
best_ant
;
rate
->
sgi
=
false
;
rate
->
ldpc
=
false
;
rate
->
bw
=
RATE_MCS_CHAN_WIDTH_20
;
rate
->
index
=
find_first_bit
(
&
lq_sta
->
active_legacy_rate
,
BITS_PER_LONG
);
if
(
band
==
IEEE80211_BAND_5GHZ
)
{
rate
->
type
=
LQ_LEGACY_A
;
initial_rates
=
rs_init_rates_5ghz
;
nentries
=
ARRAY_SIZE
(
rs_init_rates_5ghz
);
}
else
{
rate
->
type
=
LQ_LEGACY_G
;
initial_rates
=
rs_init_rates_24ghz
;
nentries
=
ARRAY_SIZE
(
rs_init_rates_24ghz
);
}
if
(
IWL_MVM_RS_RSSI_BASED_INIT_RATE
)
{
for
(
i
=
0
;
i
<
nentries
;
i
++
)
{
int
rate_idx
=
initial_rates
[
i
].
rate_idx
;
if
((
best_rssi
>=
initial_rates
[
i
].
rssi
)
&&
(
BIT
(
rate_idx
)
&
lq_sta
->
active_legacy_rate
))
{
rate
->
index
=
rate_idx
;
break
;
}
}
}
IWL_DEBUG_RATE
(
mvm
,
"rate_idx %d ANT %s
\n
"
,
rate
->
index
,
rs_pretty_ant
(
rate
->
ant
));
}
/* Save info about RSSI of last Rx */
void
rs_update_last_rssi
(
struct
iwl_mvm
*
mvm
,
struct
iwl_lq_sta
*
lq_sta
,
struct
ieee80211_rx_status
*
rx_status
)
{
lq_sta
->
pers
.
chains
=
rx_status
->
chains
;
lq_sta
->
pers
.
chain_signal
[
0
]
=
rx_status
->
chain_signal
[
0
];
lq_sta
->
pers
.
chain_signal
[
1
]
=
rx_status
->
chain_signal
[
1
];
lq_sta
->
pers
.
chain_signal
[
2
]
=
rx_status
->
chain_signal
[
2
];
}
/**
* rs_initialize_lq - Initialize a station's hardware rate table
*
...
...
@@ -2310,17 +2403,11 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
{
struct
iwl_scale_tbl_info
*
tbl
;
struct
rs_rate
*
rate
;
int
i
;
u8
active_tbl
=
0
;
u8
valid_tx_ant
;
if
(
!
sta
||
!
lq_sta
)
return
;
i
=
lq_sta
->
last_txrate_idx
;
valid_tx_ant
=
mvm
->
fw
->
valid_tx_ant
;
if
(
!
lq_sta
->
search_better_tbl
)
active_tbl
=
lq_sta
->
active_tbl
;
else
...
...
@@ -2329,18 +2416,8 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
tbl
=
&
(
lq_sta
->
lq_info
[
active_tbl
]);
rate
=
&
tbl
->
rate
;
if
((
i
<
0
)
||
(
i
>=
IWL_RATE_COUNT
))
i
=
0
;
rate
->
index
=
i
;
rate
->
ant
=
first_antenna
(
valid_tx_ant
);
rate
->
sgi
=
false
;
rate
->
ldpc
=
false
;
rate
->
bw
=
RATE_MCS_CHAN_WIDTH_20
;
if
(
band
==
IEEE80211_BAND_5GHZ
)
rate
->
type
=
LQ_LEGACY_A
;
else
rate
->
type
=
LQ_LEGACY_G
;
rs_get_initial_rate
(
mvm
,
lq_sta
,
band
,
rate
);
lq_sta
->
last_txrate_idx
=
rate
->
index
;
WARN_ON_ONCE
(
rate
->
ant
!=
ANT_A
&&
rate
->
ant
!=
ANT_B
);
if
(
rate
->
ant
==
ANT_A
)
...
...
@@ -2397,6 +2474,8 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
lq_sta
->
pers
.
dbg_fixed_rate
=
0
;
lq_sta
->
pers
.
dbg_fixed_txp_reduction
=
TPC_INVALID
;
#endif
lq_sta
->
pers
.
chains
=
0
;
memset
(
lq_sta
->
pers
.
chain_signal
,
0
,
sizeof
(
lq_sta
->
pers
.
chain_signal
));
return
&
sta_priv
->
lq_sta
;
}
...
...
@@ -2630,11 +2709,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
/* as default allow aggregation for all tids */
lq_sta
->
tx_agg_tid_en
=
IWL_AGG_ALL_TID
;
/* Set last_txrate_idx to lowest rate */
lq_sta
->
last_txrate_idx
=
rate_lowest_index
(
sband
,
sta
);
if
(
sband
->
band
==
IEEE80211_BAND_5GHZ
)
lq_sta
->
last_txrate_idx
+=
IWL_FIRST_OFDM_RATE
;
lq_sta
->
is_agg
=
0
;
#ifdef CONFIG_IWLWIFI_DEBUGFS
iwl_mvm_reset_frame_stats
(
mvm
,
&
mvm
->
drv_rx_stats
);
...
...
@@ -3238,7 +3312,7 @@ static void rs_rate_init_stub(void *mvm_r,
static
const
struct
rate_control_ops
rs_mvm_ops
=
{
.
name
=
RS_NAME
,
.
tx_status
=
rs_tx_status
,
.
tx_status
=
rs_
mac80211_
tx_status
,
.
get_rate
=
rs_get_rate
,
.
rate_init
=
rs_rate_init_stub
,
.
alloc
=
rs_alloc
,
...
...
drivers/net/wireless/iwlwifi/mvm/rs.h
浏览文件 @
d3d3e001
...
...
@@ -376,6 +376,10 @@ struct iwl_lq_sta {
void
iwl_mvm_rs_rate_init
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
,
enum
ieee80211_band
band
,
bool
init
);
/* Notify RS about Tx status */
void
iwl_mvm_rs_tx_status
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_sta
*
sta
,
int
tid
,
struct
ieee80211_tx_info
*
info
);
/**
* iwl_rate_control_register - Register the rate control algorithm callbacks
*
...
...
drivers/net/wireless/iwlwifi/mvm/rx.c
浏览文件 @
d3d3e001
...
...
@@ -246,6 +246,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct
iwl_rx_packet
*
pkt
=
rxb_addr
(
rxb
);
struct
iwl_rx_phy_info
*
phy_info
;
struct
iwl_rx_mpdu_res_start
*
rx_res
;
struct
ieee80211_sta
*
sta
;
u32
len
;
u32
ampdu_status
;
u32
rate_n_flags
;
...
...
@@ -260,23 +261,6 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
memset
(
&
rx_status
,
0
,
sizeof
(
rx_status
));
/*
* We have tx blocked stations (with CS bit). If we heard frames from
* a blocked station on a new channel we can TX to it again.
*/
if
(
unlikely
(
mvm
->
csa_tx_block_bcn_timeout
))
{
struct
ieee80211_sta
*
sta
;
rcu_read_lock
();
sta
=
ieee80211_find_sta
(
rcu_dereference
(
mvm
->
csa_tx_blocked_vif
),
hdr
->
addr2
);
if
(
sta
)
iwl_mvm_sta_modify_disable_tx_ap
(
mvm
,
sta
,
false
);
rcu_read_unlock
();
}
/*
* drop the packet if it has failed being decrypted by HW
*/
...
...
@@ -325,6 +309,29 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
IWL_DEBUG_STATS_LIMIT
(
mvm
,
"Rssi %d, TSF %llu
\n
"
,
rx_status
.
signal
,
(
unsigned
long
long
)
rx_status
.
mactime
);
rcu_read_lock
();
/*
* We have tx blocked stations (with CS bit). If we heard frames from
* a blocked station on a new channel we can TX to it again.
*/
if
(
unlikely
(
mvm
->
csa_tx_block_bcn_timeout
))
{
sta
=
ieee80211_find_sta
(
rcu_dereference
(
mvm
->
csa_tx_blocked_vif
),
hdr
->
addr2
);
if
(
sta
)
iwl_mvm_sta_modify_disable_tx_ap
(
mvm
,
sta
,
false
);
}
/* This is fine since we don't support multiple AP interfaces */
sta
=
ieee80211_find_sta_by_ifaddr
(
mvm
->
hw
,
hdr
->
addr2
,
NULL
);
if
(
sta
)
{
struct
iwl_mvm_sta
*
mvmsta
;
mvmsta
=
iwl_mvm_sta_from_mac80211
(
sta
);
rs_update_last_rssi
(
mvm
,
&
mvmsta
->
lq_sta
,
&
rx_status
);
}
rcu_read_unlock
();
/* set the preamble flag if appropriate */
if
(
phy_info
->
phy_flags
&
cpu_to_le16
(
RX_RES_PHY_FLAGS_SHORT_PREAMBLE
))
rx_status
.
flag
|=
RX_FLAG_SHORTPRE
;
...
...
drivers/net/wireless/iwlwifi/mvm/scan.c
浏览文件 @
d3d3e001
...
...
@@ -339,6 +339,55 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
}
}
static
inline
bool
iwl_mvm_rrm_scan_needed
(
struct
iwl_mvm
*
mvm
)
{
/* require rrm scan whenever the fw supports it */
return
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT
;
}
static
int
iwl_mvm_max_scan_ie_fw_cmd_room
(
struct
iwl_mvm
*
mvm
,
bool
is_sched_scan
)
{
int
max_probe_len
;
if
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_LMAC_SCAN
)
max_probe_len
=
SCAN_OFFLOAD_PROBE_REQ_SIZE
;
else
max_probe_len
=
mvm
->
fw
->
ucode_capa
.
max_probe_length
;
/* we create the 802.11 header and SSID element */
max_probe_len
-=
24
+
2
;
/* basic ssid is added only for hw_scan with and old api */
if
(
!
(
mvm
->
fw
->
ucode_capa
.
flags
&
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID
)
&&
!
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_LMAC_SCAN
)
&&
!
is_sched_scan
)
max_probe_len
-=
32
;
return
max_probe_len
;
}
int
iwl_mvm_max_scan_ie_len
(
struct
iwl_mvm
*
mvm
,
bool
is_sched_scan
)
{
int
max_ie_len
=
iwl_mvm_max_scan_ie_fw_cmd_room
(
mvm
,
is_sched_scan
);
if
(
!
(
mvm
->
fw
->
ucode_capa
.
api
[
0
]
&
IWL_UCODE_TLV_API_LMAC_SCAN
))
return
max_ie_len
;
/* TODO: [BUG] This function should return the maximum allowed size of
* scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
* in the same command. So the correct implementation of this function
* is just iwl_mvm_max_scan_ie_fw_cmd_room() / 2. Currently the scan
* command has only 512 bytes and it would leave us with about 240
* bytes for scan IEs, which is clearly not enough. So meanwhile
* we will report an incorrect value. This may result in a failure to
* issue a scan in unified_scan_lmac and unified_sched_scan_lmac
* functions with -ENOBUFS, if a large enough probe will be provided.
*/
return
max_ie_len
;
}
int
iwl_mvm_scan_request
(
struct
iwl_mvm
*
mvm
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_scan_request
*
req
)
...
...
@@ -1153,6 +1202,10 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE
|
IWL_SCAN_CHANNEL_FLAG_CACHE_ADD
);
}
if
(
iwl_mvm_rrm_scan_needed
(
mvm
))
cmd
->
scan_flags
|=
cpu_to_le32
(
IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED
);
}
int
iwl_mvm_unified_scan_lmac
(
struct
iwl_mvm
*
mvm
,
...
...
@@ -1180,13 +1233,12 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
if
(
WARN_ON
(
mvm
->
scan_cmd
==
NULL
))
return
-
ENOMEM
;
if
(
WARN_ON_ONCE
(
req
->
req
.
n_ssids
>
PROBE_OPTION_MAX
||
req
->
ies
.
common_ie_len
+
req
->
ies
.
len
[
0
]
+
req
->
ies
.
len
[
1
]
+
24
+
2
>
SCAN_OFFLOAD_PROBE_REQ_SIZE
||
req
->
req
.
n_channels
>
mvm
->
fw
->
ucode_capa
.
n_scan_channels
))
return
-
1
;
if
(
req
->
req
.
n_ssids
>
PROBE_OPTION_MAX
||
req
->
ies
.
common_ie_len
+
req
->
ies
.
len
[
NL80211_BAND_2GHZ
]
+
req
->
ies
.
len
[
NL80211_BAND_5GHZ
]
>
iwl_mvm_max_scan_ie_fw_cmd_room
(
mvm
,
false
)
||
req
->
req
.
n_channels
>
mvm
->
fw
->
ucode_capa
.
n_scan_channels
)
return
-
ENOBUFS
;
mvm
->
scan_status
=
IWL_MVM_SCAN_OS
;
...
...
@@ -1208,7 +1260,7 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
if
(
req
->
req
.
n_ssids
==
0
)
flags
|=
IWL_MVM_LMAC_SCAN_FLAG_PASSIVE
;
cmd
->
scan_flags
=
cpu_to_le32
(
flags
);
cmd
->
scan_flags
|
=
cpu_to_le32
(
flags
);
cmd
->
flags
=
iwl_mvm_scan_rxon_flags
(
req
->
req
.
channels
[
0
]
->
band
);
cmd
->
filter_flags
=
cpu_to_le32
(
MAC_FILTER_ACCEPT_GRP
|
...
...
@@ -1274,10 +1326,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
if
(
WARN_ON
(
mvm
->
scan_cmd
==
NULL
))
return
-
ENOMEM
;
if
(
WARN_ON_ONCE
(
req
->
n_ssids
>
PROBE_OPTION_MAX
||
ies
->
common_ie_len
+
ies
->
len
[
0
]
+
ies
->
len
[
1
]
+
24
+
2
>
SCAN_OFFLOAD_PROBE_REQ_SIZE
||
req
->
n_channels
>
mvm
->
fw
->
ucode_capa
.
n_scan_channels
))
if
(
req
->
n_ssids
>
PROBE_OPTION_MAX
||
ies
->
common_ie_len
+
ies
->
len
[
NL80211_BAND_2GHZ
]
+
ies
->
len
[
NL80211_BAND_5GHZ
]
>
iwl_mvm_max_scan_ie_fw_cmd_room
(
mvm
,
true
)
||
req
->
n_channels
>
mvm
->
fw
->
ucode_capa
.
n_scan_channels
)
return
-
ENOBUFS
;
iwl_mvm_scan_calc_params
(
mvm
,
vif
,
req
->
n_ssids
,
0
,
&
params
);
...
...
@@ -1305,7 +1358,7 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
if
(
req
->
n_ssids
==
0
)
flags
|=
IWL_MVM_LMAC_SCAN_FLAG_PASSIVE
;
cmd
->
scan_flags
=
cpu_to_le32
(
flags
);
cmd
->
scan_flags
|
=
cpu_to_le32
(
flags
);
cmd
->
flags
=
iwl_mvm_scan_rxon_flags
(
req
->
channels
[
0
]
->
band
);
cmd
->
filter_flags
=
cpu_to_le32
(
MAC_FILTER_ACCEPT_GRP
|
...
...
drivers/net/wireless/iwlwifi/mvm/sta.c
浏览文件 @
d3d3e001
...
...
@@ -247,6 +247,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
memset
(
&
mvm_sta
->
tid_data
[
i
],
0
,
sizeof
(
mvm_sta
->
tid_data
[
i
]));
mvm_sta
->
tid_data
[
i
].
seq_number
=
seq
;
}
mvm_sta
->
agg_tids
=
0
;
ret
=
iwl_mvm_sta_send_to_fw
(
mvm
,
sta
,
false
);
if
(
ret
)
...
...
@@ -535,8 +536,8 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
lockdep_assert_held
(
&
mvm
->
mutex
);
/* Map Aux queue to fifo - needs to happen before adding Aux station */
iwl_
trans_ac_txq_enable
(
mvm
->
trans
,
mvm
->
aux_queue
,
IWL_MVM_TX_FIFO_MCAST
);
iwl_
mvm_enable_ac_txq
(
mvm
,
mvm
->
aux_queue
,
IWL_MVM_TX_FIFO_MCAST
);
/* Allocate aux station and assign to it the aux queue */
ret
=
iwl_mvm_allocate_int_sta
(
mvm
,
&
mvm
->
aux_sta
,
BIT
(
mvm
->
aux_queue
),
...
...
@@ -872,12 +873,16 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int
queue
,
fifo
,
ret
;
u16
ssn
;
BUILD_BUG_ON
((
sizeof
(
mvmsta
->
agg_tids
)
*
BITS_PER_BYTE
)
!=
IWL_MAX_TID_COUNT
);
buf_size
=
min_t
(
int
,
buf_size
,
LINK_QUAL_AGG_FRAME_LIMIT_DEF
);
spin_lock_bh
(
&
mvmsta
->
lock
);
ssn
=
tid_data
->
ssn
;
queue
=
tid_data
->
txq_id
;
tid_data
->
state
=
IWL_AGG_ON
;
mvmsta
->
agg_tids
|=
BIT
(
tid
);
tid_data
->
ssn
=
0xffff
;
spin_unlock_bh
(
&
mvmsta
->
lock
);
...
...
@@ -887,8 +892,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if
(
ret
)
return
-
EIO
;
iwl_
trans_txq_enable
(
mvm
->
trans
,
queue
,
fifo
,
mvmsta
->
sta_id
,
tid
,
buf_size
,
ssn
);
iwl_
mvm_enable_agg_txq
(
mvm
,
queue
,
fifo
,
mvmsta
->
sta_id
,
tid
,
buf_size
,
ssn
);
/*
* Even though in theory the peer could have different
...
...
@@ -932,6 +937,8 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
IWL_DEBUG_TX_QUEUES
(
mvm
,
"Stop AGG: sta %d tid %d q %d state %d
\n
"
,
mvmsta
->
sta_id
,
tid
,
txq_id
,
tid_data
->
state
);
mvmsta
->
agg_tids
&=
~
BIT
(
tid
);
switch
(
tid_data
->
state
)
{
case
IWL_AGG_ON
:
tid_data
->
ssn
=
IEEE80211_SEQ_TO_SN
(
tid_data
->
seq_number
);
...
...
@@ -956,7 +963,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
iwl_mvm_sta_tx_agg
(
mvm
,
sta
,
tid
,
txq_id
,
false
);
iwl_
trans_txq_disable
(
mvm
->
trans
,
txq_id
,
true
);
iwl_
mvm_disable_txq
(
mvm
,
txq_id
);
return
0
;
case
IWL_AGG_STARTING
:
case
IWL_EMPTYING_HW_QUEUE_ADDBA
:
...
...
@@ -1005,6 +1012,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvmsta
->
sta_id
,
tid
,
txq_id
,
tid_data
->
state
);
old_state
=
tid_data
->
state
;
tid_data
->
state
=
IWL_AGG_OFF
;
mvmsta
->
agg_tids
&=
~
BIT
(
tid
);
spin_unlock_bh
(
&
mvmsta
->
lock
);
if
(
old_state
>=
IWL_AGG_ON
)
{
...
...
@@ -1013,7 +1021,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
iwl_mvm_sta_tx_agg
(
mvm
,
sta
,
tid
,
txq_id
,
false
);
iwl_
trans_txq_disable
(
mvm
->
trans
,
tid_data
->
txq_id
,
true
);
iwl_
mvm_disable_txq
(
mvm
,
tid_data
->
txq_id
);
}
mvm
->
queue_to_mac80211
[
tid_data
->
txq_id
]
=
...
...
drivers/net/wireless/iwlwifi/mvm/sta.h
浏览文件 @
d3d3e001
...
...
@@ -299,6 +299,7 @@ static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data)
* @tx_protection: reference counter for controlling the Tx protection.
* @tt_tx_protection: is thermal throttling enable Tx protection?
* @disable_tx: is tx to this STA disabled?
* @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON)
*
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
* in the structure for use by driver. This structure is placed in that
...
...
@@ -323,6 +324,7 @@ struct iwl_mvm_sta {
bool
tt_tx_protection
;
bool
disable_tx
;
u8
agg_tids
;
};
static
inline
struct
iwl_mvm_sta
*
...
...
drivers/net/wireless/iwlwifi/mvm/tt.c
浏览文件 @
d3d3e001
...
...
@@ -135,7 +135,7 @@ static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
sizeof
(
cmd
),
&
cmd
);
}
static
int
iwl_mvm_get_temp
(
struct
iwl_mvm
*
mvm
)
int
iwl_mvm_get_temp
(
struct
iwl_mvm
*
mvm
)
{
struct
iwl_notification_wait
wait_temp_notif
;
static
const
u8
temp_notif
[]
=
{
DTS_MEASUREMENT_NOTIFICATION
};
...
...
drivers/net/wireless/iwlwifi/mvm/tx.c
浏览文件 @
d3d3e001
...
...
@@ -133,6 +133,11 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
!
is_multicast_ether_addr
(
ieee80211_get_DA
(
hdr
)))
tx_flags
|=
TX_CMD_FLG_PROT_REQUIRE
;
if
((
mvm
->
fw
->
ucode_capa
.
capa
[
0
]
&
IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT
)
&&
ieee80211_action_contains_tpc
(
skb
))
tx_flags
|=
TX_CMD_FLG_WRITE_TX_POWER
;
tx_cmd
->
tx_flags
=
cpu_to_le32
(
tx_flags
);
/* Total # bytes to be transmitted */
tx_cmd
->
len
=
cpu_to_le16
((
u16
)
skb
->
len
);
...
...
@@ -488,11 +493,11 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
IWL_DEBUG_TX_QUEUES
(
mvm
,
"Can continue DELBA flow ssn = next_recl = %d
\n
"
,
tid_data
->
next_reclaimed
);
iwl_
trans_txq_disable
(
mvm
->
trans
,
tid_data
->
txq_id
,
true
);
iwl_
mvm_disable_txq
(
mvm
,
tid_data
->
txq_id
);
tid_data
->
state
=
IWL_AGG_OFF
;
/*
* we can't hold the mutex - but since we are after a sequence
* point (call to iwl_
trans_txq_disable
), so we don't even need
* point (call to iwl_
mvm_disable_txq(
), so we don't even need
* a memory barrier.
*/
mvm
->
queue_to_mac80211
[
tid_data
->
txq_id
]
=
...
...
@@ -868,6 +873,19 @@ int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
return
0
;
}
static
void
iwl_mvm_tx_info_from_ba_notif
(
struct
ieee80211_tx_info
*
info
,
struct
iwl_mvm_ba_notif
*
ba_notif
,
struct
iwl_mvm_tid_data
*
tid_data
)
{
info
->
flags
|=
IEEE80211_TX_STAT_AMPDU
;
info
->
status
.
ampdu_ack_len
=
ba_notif
->
txed_2_done
;
info
->
status
.
ampdu_len
=
ba_notif
->
txed
;
iwl_mvm_hwrate_to_tx_status
(
tid_data
->
rate_n_flags
,
info
);
info
->
status
.
status_driver_data
[
0
]
=
(
void
*
)(
uintptr_t
)
tid_data
->
reduced_tpc
;
}
int
iwl_mvm_rx_ba_notif
(
struct
iwl_mvm
*
mvm
,
struct
iwl_rx_cmd_buffer
*
rxb
,
struct
iwl_device_cmd
*
cmd
)
{
...
...
@@ -954,21 +972,37 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
*/
info
->
flags
|=
IEEE80211_TX_STAT_ACK
;
if
(
freed
==
1
)
{
/* this is the first skb we deliver in this batch */
/* put the rate scaling data there */
info
->
flags
|=
IEEE80211_TX_STAT_AMPDU
;
info
->
status
.
ampdu_ack_len
=
ba_notif
->
txed_2_done
;
info
->
status
.
ampdu_len
=
ba_notif
->
txed
;
iwl_mvm_hwrate_to_tx_status
(
tid_data
->
rate_n_flags
,
info
);
info
->
status
.
status_driver_data
[
0
]
=
(
void
*
)(
uintptr_t
)
tid_data
->
reduced_tpc
;
}
/* this is the first skb we deliver in this batch */
/* put the rate scaling data there */
if
(
freed
==
1
)
iwl_mvm_tx_info_from_ba_notif
(
info
,
ba_notif
,
tid_data
);
}
spin_unlock_bh
(
&
mvmsta
->
lock
);
/* We got a BA notif with 0 acked or scd_ssn didn't progress which is
* possible (i.e. first MPDU in the aggregation wasn't acked)
* Still it's important to update RS about sent vs. acked.
*/
if
(
skb_queue_empty
(
&
reclaimed_skbs
))
{
struct
ieee80211_tx_info
ba_info
=
{};
struct
ieee80211_chanctx_conf
*
chanctx_conf
=
NULL
;
if
(
mvmsta
->
vif
)
chanctx_conf
=
rcu_dereference
(
mvmsta
->
vif
->
chanctx_conf
);
if
(
WARN_ON_ONCE
(
!
chanctx_conf
))
goto
out
;
ba_info
.
band
=
chanctx_conf
->
def
.
chan
->
band
;
iwl_mvm_tx_info_from_ba_notif
(
&
ba_info
,
ba_notif
,
tid_data
);
IWL_DEBUG_TX_REPLY
(
mvm
,
"No reclaim. Update rs directly
\n
"
);
iwl_mvm_rs_tx_status
(
mvm
,
sta
,
tid
,
&
ba_info
);
}
out:
rcu_read_unlock
();
while
(
!
skb_queue_empty
(
&
reclaimed_skbs
))
{
...
...
drivers/net/wireless/iwlwifi/mvm/utils.c
浏览文件 @
d3d3e001
...
...
@@ -530,6 +530,52 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
iwl_mvm_dump_umac_error_log
(
mvm
);
}
void
iwl_mvm_enable_txq
(
struct
iwl_mvm
*
mvm
,
int
queue
,
u16
ssn
,
const
struct
iwl_trans_txq_scd_cfg
*
cfg
)
{
if
(
iwl_mvm_is_dqa_supported
(
mvm
))
{
struct
iwl_scd_txq_cfg_cmd
cmd
=
{
.
scd_queue
=
queue
,
.
enable
=
1
,
.
window
=
cfg
->
frame_limit
,
.
sta_id
=
cfg
->
sta_id
,
.
ssn
=
cpu_to_le16
(
ssn
),
.
tx_fifo
=
cfg
->
fifo
,
.
aggregate
=
cfg
->
aggregate
,
.
flags
=
IWL_SCD_FLAGS_DQA_ENABLED
,
.
tid
=
cfg
->
tid
,
.
control
=
IWL_SCD_CONTROL_SET_SSN
,
};
int
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
SCD_QUEUE_CFG
,
0
,
sizeof
(
cmd
),
&
cmd
);
if
(
ret
)
IWL_ERR
(
mvm
,
"Failed to configure queue %d on FIFO %d
\n
"
,
queue
,
cfg
->
fifo
);
}
iwl_trans_txq_enable_cfg
(
mvm
->
trans
,
queue
,
ssn
,
iwl_mvm_is_dqa_supported
(
mvm
)
?
NULL
:
cfg
);
}
void
iwl_mvm_disable_txq
(
struct
iwl_mvm
*
mvm
,
int
queue
)
{
iwl_trans_txq_disable
(
mvm
->
trans
,
queue
,
!
iwl_mvm_is_dqa_supported
(
mvm
));
if
(
iwl_mvm_is_dqa_supported
(
mvm
))
{
struct
iwl_scd_txq_cfg_cmd
cmd
=
{
.
scd_queue
=
queue
,
.
enable
=
0
,
};
int
ret
=
iwl_mvm_send_cmd_pdu
(
mvm
,
SCD_QUEUE_CFG
,
CMD_ASYNC
,
sizeof
(
cmd
),
&
cmd
);
if
(
ret
)
IWL_ERR
(
mvm
,
"Failed to disable queue %d (ret=%d)
\n
"
,
queue
,
ret
);
}
}
/**
* iwl_mvm_send_lq_cmd() - Send link quality command
* @init: This command is sent as part of station initialization right
...
...
drivers/net/wireless/iwlwifi/pcie/drv.c
浏览文件 @
d3d3e001
...
...
@@ -275,6 +275,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4070
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4072
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4170
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4C60
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4C70
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4060
,
iwl7260_2n_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x406A
,
iwl7260_2n_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0x4160
,
iwl7260_2n_cfg
)},
...
...
@@ -318,6 +320,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{
IWL_PCI_DEVICE
(
0x08B1
,
0xC770
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0xC760
,
iwl7260_2n_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B2
,
0xC270
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0xCC70
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B1
,
0xCC60
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B2
,
0xC272
,
iwl7260_2ac_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B2
,
0xC260
,
iwl7260_2n_cfg
)},
{
IWL_PCI_DEVICE
(
0x08B2
,
0xC26A
,
iwl7260_n_cfg
)},
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
浏览文件 @
d3d3e001
...
...
@@ -2190,7 +2190,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
*/
if
(
trans
->
cfg
->
device_family
==
IWL_DEVICE_FAMILY_8000
)
trans
->
hw_rev
=
(
trans
->
hw_rev
&
0xfff0
)
|
(
CSR_HW_REV_STEP
(
trans
->
hw_rev
<<
2
));
(
CSR_HW_REV_STEP
(
trans
->
hw_rev
<<
2
)
<<
2
);
trans
->
hw_id
=
(
pdev
->
device
<<
16
)
+
pdev
->
subsystem_device
;
snprintf
(
trans
->
hw_id_str
,
sizeof
(
trans
->
hw_id_str
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录