Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
48c6cc04
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
48c6cc04
编写于
1月 07, 2013
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
上级
ba23d206
abae2386
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
311 addition
and
386 deletion
+311
-386
drivers/net/wireless/iwlwifi/dvm/commands.h
drivers/net/wireless/iwlwifi/dvm/commands.h
+4
-4
drivers/net/wireless/iwlwifi/dvm/debugfs.c
drivers/net/wireless/iwlwifi/dvm/debugfs.c
+2
-2
drivers/net/wireless/iwlwifi/dvm/led.c
drivers/net/wireless/iwlwifi/dvm/led.c
+1
-1
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
+4
-4
drivers/net/wireless/iwlwifi/dvm/main.c
drivers/net/wireless/iwlwifi/dvm/main.c
+11
-10
drivers/net/wireless/iwlwifi/dvm/tt.c
drivers/net/wireless/iwlwifi/dvm/tt.c
+2
-2
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/iwlwifi/dvm/tx.c
+10
-11
drivers/net/wireless/iwlwifi/dvm/ucode.c
drivers/net/wireless/iwlwifi/dvm/ucode.c
+1
-95
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-csr.h
+2
-2
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-io.c
+22
-146
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-io.h
+2
-19
drivers/net/wireless/iwlwifi/iwl-test.c
drivers/net/wireless/iwlwifi/iwl-test.c
+29
-24
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/iwl-trans.h
+65
-4
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/internal.h
+2
-4
drivers/net/wireless/iwlwifi/pcie/rx.c
drivers/net/wireless/iwlwifi/pcie/rx.c
+2
-0
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/trans.c
+135
-44
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+17
-14
未找到文件。
drivers/net/wireless/iwlwifi/dvm/commands.h
浏览文件 @
48c6cc04
...
...
@@ -3695,7 +3695,7 @@ struct iwl_bt_uart_msg {
u8
frame5
;
u8
frame6
;
u8
frame7
;
}
__
attribute__
((
packed
))
;
}
__
packed
;
struct
iwl_bt_coex_profile_notif
{
struct
iwl_bt_uart_msg
last_bt_uart_msg
;
...
...
@@ -3703,7 +3703,7 @@ struct iwl_bt_coex_profile_notif {
u8
bt_traffic_load
;
/* 0 .. 3? */
u8
bt_ci_compliance
;
/* 0 - not complied, 1 - complied */
u8
reserved
;
}
__
attribute__
((
packed
))
;
}
__
packed
;
#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0
#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1
...
...
@@ -3752,7 +3752,7 @@ enum bt_coex_prio_table_priorities {
struct
iwl_bt_coex_prio_table_cmd
{
u8
prio_tbl
[
BT_COEX_PRIO_TBL_EVT_MAX
];
}
__
attribute__
((
packed
))
;
}
__
packed
;
#define IWL_BT_COEX_ENV_CLOSE 0
#define IWL_BT_COEX_ENV_OPEN 1
...
...
@@ -3764,7 +3764,7 @@ struct iwl_bt_coex_prot_env_cmd {
u8
action
;
/* 0 = closed, 1 = open */
u8
type
;
/* 0 .. 15 */
u8
reserved
[
2
];
}
__
attribute__
((
packed
))
;
}
__
packed
;
/*
* REPLY_D3_CONFIG
...
...
drivers/net/wireless/iwlwifi/dvm/debugfs.c
浏览文件 @
48c6cc04
...
...
@@ -157,7 +157,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
sram
=
priv
->
dbgfs_sram_offset
&
~
0x3
;
/* read the first u32 from sram */
val
=
iwl_
read_targ_mem
(
priv
->
trans
,
sram
);
val
=
iwl_
trans_read_mem32
(
priv
->
trans
,
sram
);
for
(;
len
;
len
--
)
{
/* put the address at the start of every line */
...
...
@@ -176,7 +176,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
if
(
++
offset
==
4
)
{
sram
+=
4
;
offset
=
0
;
val
=
iwl_
read_targ_mem
(
priv
->
trans
,
sram
);
val
=
iwl_
trans_read_mem32
(
priv
->
trans
,
sram
);
}
/* put in extra spaces and split lines for human readability */
...
...
drivers/net/wireless/iwlwifi/dvm/led.c
浏览文件 @
48c6cc04
...
...
@@ -69,7 +69,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = {
/* Set led register off */
void
iwlagn_led_enable
(
struct
iwl_priv
*
priv
)
{
iwl_write32
(
priv
->
trans
,
CSR_LED_REG
,
CSR_LED_REG_T
RU
N_ON
);
iwl_write32
(
priv
->
trans
,
CSR_LED_REG
,
CSR_LED_REG_T
UR
N_ON
);
}
/*
...
...
drivers/net/wireless/iwlwifi/dvm/mac80211.c
浏览文件 @
48c6cc04
...
...
@@ -459,11 +459,11 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
base
=
priv
->
device_pointers
.
error_event_table
;
if
(
iwlagn_hw_valid_rtc_data_addr
(
base
))
{
spin_lock_irqsave
(
&
priv
->
trans
->
reg_lock
,
flags
);
ret
=
iwl_grab_nic_access_silent
(
priv
->
trans
);
if
(
likely
(
ret
==
0
))
{
if
(
iwl_trans_grab_nic_access
(
priv
->
trans
,
true
))
{
iwl_write32
(
priv
->
trans
,
HBUS_TARG_MEM_RADDR
,
base
);
status
=
iwl_read32
(
priv
->
trans
,
HBUS_TARG_MEM_RDAT
);
iwl_release_nic_access
(
priv
->
trans
);
iwl_trans_release_nic_access
(
priv
->
trans
);
ret
=
0
;
}
spin_unlock_irqrestore
(
&
priv
->
trans
->
reg_lock
,
flags
);
...
...
@@ -479,7 +479,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
}
if
(
priv
->
wowlan_sram
)
_iwl_read_targ_mem_dwords
(
iwl_trans_read_mem
(
priv
->
trans
,
0x800000
,
priv
->
wowlan_sram
,
img
->
sec
[
IWL_UCODE_SECTION_DATA
].
len
/
4
);
...
...
drivers/net/wireless/iwlwifi/dvm/main.c
浏览文件 @
48c6cc04
...
...
@@ -354,7 +354,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
/* Make sure device is powered up for SRAM reads */
spin_lock_irqsave
(
&
priv
->
trans
->
reg_lock
,
reg_flags
);
if
(
unlikely
(
!
iwl_grab_nic_access
(
priv
->
trans
)
))
{
if
(
!
iwl_trans_grab_nic_access
(
priv
->
trans
,
false
))
{
spin_unlock_irqrestore
(
&
priv
->
trans
->
reg_lock
,
reg_flags
);
return
;
}
...
...
@@ -388,7 +388,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
}
}
/* Allow device to power down */
iwl_release_nic_access
(
priv
->
trans
);
iwl_
trans_
release_nic_access
(
priv
->
trans
);
spin_unlock_irqrestore
(
&
priv
->
trans
->
reg_lock
,
reg_flags
);
}
...
...
@@ -408,7 +408,8 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
base
=
priv
->
device_pointers
.
log_event_table
;
if
(
iwlagn_hw_valid_rtc_data_addr
(
base
))
{
iwl_read_targ_mem_bytes
(
priv
->
trans
,
base
,
&
read
,
sizeof
(
read
));
iwl_trans_read_mem_bytes
(
priv
->
trans
,
base
,
&
read
,
sizeof
(
read
));
capacity
=
read
.
capacity
;
mode
=
read
.
mode
;
num_wraps
=
read
.
wrap_counter
;
...
...
@@ -1627,7 +1628,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
}
/*TODO: Update dbgfs with ISR error stats obtained below */
iwl_
read_targ
_mem_bytes
(
trans
,
base
,
&
table
,
sizeof
(
table
));
iwl_
trans_read
_mem_bytes
(
trans
,
base
,
&
table
,
sizeof
(
table
));
if
(
ERROR_START_OFFSET
<=
table
.
valid
*
ERROR_ELEM_SIZE
)
{
IWL_ERR
(
trans
,
"Start IWL Error Log Dump:
\n
"
);
...
...
@@ -1717,7 +1718,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
/* Make sure device is powered up for SRAM reads */
spin_lock_irqsave
(
&
trans
->
reg_lock
,
reg_flags
);
if
(
unlikely
(
!
iwl_grab_nic_access
(
trans
)
))
if
(
!
iwl_trans_grab_nic_access
(
trans
,
false
))
goto
out_unlock
;
/* Set starting address; reads will auto-increment */
...
...
@@ -1756,7 +1757,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
}
/* Allow device to power down */
iwl_release_nic_access
(
trans
);
iwl_
trans_
release_nic_access
(
trans
);
out_unlock:
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
reg_flags
);
return
pos
;
...
...
@@ -1835,10 +1836,10 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
}
/* event log header */
capacity
=
iwl_
read_targ_mem
(
trans
,
base
);
mode
=
iwl_
read_targ_mem
(
trans
,
base
+
(
1
*
sizeof
(
u32
)));
num_wraps
=
iwl_
read_targ_mem
(
trans
,
base
+
(
2
*
sizeof
(
u32
)));
next_entry
=
iwl_
read_targ_mem
(
trans
,
base
+
(
3
*
sizeof
(
u32
)));
capacity
=
iwl_
trans_read_mem32
(
trans
,
base
);
mode
=
iwl_
trans_read_mem32
(
trans
,
base
+
(
1
*
sizeof
(
u32
)));
num_wraps
=
iwl_
trans_read_mem32
(
trans
,
base
+
(
2
*
sizeof
(
u32
)));
next_entry
=
iwl_
trans_read_mem32
(
trans
,
base
+
(
3
*
sizeof
(
u32
)));
if
(
capacity
>
logsize
)
{
IWL_ERR
(
priv
,
"Log capacity %d is bogus, limit to %d "
...
...
drivers/net/wireless/iwlwifi/dvm/tt.c
浏览文件 @
48c6cc04
...
...
@@ -186,8 +186,8 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
}
iwl_read32
(
priv
->
trans
,
CSR_UCODE_DRV_GP1
);
spin_lock_irqsave
(
&
priv
->
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
priv
->
trans
)
))
iwl_release_nic_access
(
priv
->
trans
);
if
(
iwl_trans_grab_nic_access
(
priv
->
trans
,
false
))
iwl_
trans_
release_nic_access
(
priv
->
trans
);
spin_unlock_irqrestore
(
&
priv
->
trans
->
reg_lock
,
flags
);
/* Reschedule the ct_kill timer to occur in
...
...
drivers/net/wireless/iwlwifi/dvm/tx.c
浏览文件 @
48c6cc04
...
...
@@ -541,9 +541,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
spin_lock_bh
(
&
priv
->
sta_lock
);
tid_data
=
&
priv
->
tid_data
[
sta_id
][
tid
];
txq_id
=
priv
->
tid_data
[
sta_id
][
tid
].
agg
.
txq_id
;
txq_id
=
tid_data
->
agg
.
txq_id
;
switch
(
priv
->
tid_data
[
sta_id
][
tid
].
agg
.
state
)
{
switch
(
tid_data
->
agg
.
state
)
{
case
IWL_EMPTYING_HW_QUEUE_ADDBA
:
/*
* This can happen if the peer stops aggregation
...
...
@@ -563,9 +563,9 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
case
IWL_AGG_ON
:
break
;
default:
IWL_WARN
(
priv
,
"Stopping AGG while state not ON "
"
or starting for %d on %d (%d)
\n
"
,
sta_id
,
tid
,
priv
->
tid_data
[
sta_id
][
tid
].
agg
.
state
);
IWL_WARN
(
priv
,
"
Stopping AGG while state not ON or starting for %d on %d (%d)
\n
"
,
sta_id
,
tid
,
tid_data
->
agg
.
state
);
spin_unlock_bh
(
&
priv
->
sta_lock
);
return
0
;
}
...
...
@@ -578,12 +578,11 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
"stopping AGG on STA/TID %d/%d but hwq %d not used
\n
"
,
sta_id
,
tid
,
txq_id
);
}
else
if
(
tid_data
->
agg
.
ssn
!=
tid_data
->
next_reclaimed
)
{
IWL_DEBUG_TX_QUEUES
(
priv
,
"Can't proceed: ssn %d, "
"next_recl = %d
\n
"
,
IWL_DEBUG_TX_QUEUES
(
priv
,
"
Can't proceed: ssn %d,
next_recl = %d
\n
"
,
tid_data
->
agg
.
ssn
,
tid_data
->
next_reclaimed
);
priv
->
tid_data
[
sta_id
][
tid
].
agg
.
state
=
IWL_EMPTYING_HW_QUEUE_DELBA
;
tid_data
->
agg
.
state
=
IWL_EMPTYING_HW_QUEUE_DELBA
;
spin_unlock_bh
(
&
priv
->
sta_lock
);
return
0
;
}
...
...
@@ -591,8 +590,8 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
IWL_DEBUG_TX_QUEUES
(
priv
,
"Can proceed: ssn = next_recl = %d
\n
"
,
tid_data
->
agg
.
ssn
);
turn_off:
agg_state
=
priv
->
tid_data
[
sta_id
][
tid
].
agg
.
state
;
priv
->
tid_data
[
sta_id
][
tid
].
agg
.
state
=
IWL_AGG_OFF
;
agg_state
=
tid_data
->
agg
.
state
;
tid_data
->
agg
.
state
=
IWL_AGG_OFF
;
spin_unlock_bh
(
&
priv
->
sta_lock
);
...
...
drivers/net/wireless/iwlwifi/dvm/ucode.c
浏览文件 @
48c6cc04
...
...
@@ -286,89 +286,6 @@ static int iwl_alive_notify(struct iwl_priv *priv)
return
iwl_send_calib_results
(
priv
);
}
/**
* iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
static
int
iwl_verify_sec_sparse
(
struct
iwl_priv
*
priv
,
const
struct
fw_desc
*
fw_desc
)
{
__le32
*
image
=
(
__le32
*
)
fw_desc
->
data
;
u32
len
=
fw_desc
->
len
;
u32
val
;
u32
i
;
IWL_DEBUG_FW
(
priv
,
"ucode inst image size is %u
\n
"
,
len
);
for
(
i
=
0
;
i
<
len
;
i
+=
100
,
image
+=
100
/
sizeof
(
u32
))
{
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
iwl_write_direct32
(
priv
->
trans
,
HBUS_TARG_MEM_RADDR
,
i
+
fw_desc
->
offset
);
val
=
iwl_read32
(
priv
->
trans
,
HBUS_TARG_MEM_RDAT
);
if
(
val
!=
le32_to_cpu
(
*
image
))
return
-
EIO
;
}
return
0
;
}
static
void
iwl_print_mismatch_sec
(
struct
iwl_priv
*
priv
,
const
struct
fw_desc
*
fw_desc
)
{
__le32
*
image
=
(
__le32
*
)
fw_desc
->
data
;
u32
len
=
fw_desc
->
len
;
u32
val
;
u32
offs
;
int
errors
=
0
;
IWL_DEBUG_FW
(
priv
,
"ucode inst image size is %u
\n
"
,
len
);
iwl_write_direct32
(
priv
->
trans
,
HBUS_TARG_MEM_RADDR
,
fw_desc
->
offset
);
for
(
offs
=
0
;
offs
<
len
&&
errors
<
20
;
offs
+=
sizeof
(
u32
),
image
++
)
{
/* read data comes through single port, auto-incr addr */
val
=
iwl_read32
(
priv
->
trans
,
HBUS_TARG_MEM_RDAT
);
if
(
val
!=
le32_to_cpu
(
*
image
))
{
IWL_ERR
(
priv
,
"uCode INST section at "
"offset 0x%x, is 0x%x, s/b 0x%x
\n
"
,
offs
,
val
,
le32_to_cpu
(
*
image
));
errors
++
;
}
}
}
/**
* iwl_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
static
int
iwl_verify_ucode
(
struct
iwl_priv
*
priv
,
enum
iwl_ucode_type
ucode_type
)
{
const
struct
fw_img
*
img
=
iwl_get_ucode_image
(
priv
,
ucode_type
);
if
(
!
img
)
{
IWL_ERR
(
priv
,
"Invalid ucode requested (%d)
\n
"
,
ucode_type
);
return
-
EINVAL
;
}
if
(
!
iwl_verify_sec_sparse
(
priv
,
&
img
->
sec
[
IWL_UCODE_SECTION_INST
]))
{
IWL_DEBUG_FW
(
priv
,
"uCode is good in inst SRAM
\n
"
);
return
0
;
}
IWL_ERR
(
priv
,
"UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!
\n
"
);
iwl_print_mismatch_sec
(
priv
,
&
img
->
sec
[
IWL_UCODE_SECTION_INST
]);
return
-
EIO
;
}
struct
iwl_alive_data
{
bool
valid
;
u8
subtype
;
...
...
@@ -426,7 +343,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
alive_cmd
,
ARRAY_SIZE
(
alive_cmd
),
iwl_alive_fn
,
&
alive_data
);
ret
=
iwl_trans_start_fw
(
priv
->
trans
,
fw
);
ret
=
iwl_trans_start_fw
(
priv
->
trans
,
fw
,
false
);
if
(
ret
)
{
priv
->
cur_ucode
=
old_type
;
iwl_remove_notification
(
&
priv
->
notif_wait
,
&
alive_wait
);
...
...
@@ -450,18 +367,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
return
-
EIO
;
}
/*
* This step takes a long time (60-80ms!!) and
* WoWLAN image should be loaded quickly, so
* skip it for WoWLAN.
*/
if
(
ucode_type
!=
IWL_UCODE_WOWLAN
)
{
ret
=
iwl_verify_ucode
(
priv
,
ucode_type
);
if
(
ret
)
{
priv
->
cur_ucode
=
old_type
;
return
ret
;
}
/* delay a bit to give rfkill time to run */
msleep
(
5
);
}
...
...
drivers/net/wireless/iwlwifi/iwl-csr.h
浏览文件 @
48c6cc04
...
...
@@ -381,8 +381,8 @@
/* LED */
#define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF)
#define CSR_LED_REG_T
RUN_ON (0x78
)
#define CSR_LED_REG_T
RUN_OFF (0x38
)
#define CSR_LED_REG_T
URN_ON (0x60
)
#define CSR_LED_REG_T
URN_OFF (0x20
)
/* ANA_PLL */
#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
...
...
drivers/net/wireless/iwlwifi/iwl-io.c
浏览文件 @
48c6cc04
...
...
@@ -35,12 +35,12 @@
#define IWL_POLL_INTERVAL 10
/* microseconds */
static
inline
void
__iwl_set_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
)
void
__iwl_set_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
)
{
iwl_write32
(
trans
,
reg
,
iwl_read32
(
trans
,
reg
)
|
mask
);
}
static
inline
void
__iwl_clear_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
)
void
__iwl_clear_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
)
{
iwl_write32
(
trans
,
reg
,
iwl_read32
(
trans
,
reg
)
&
~
mask
);
}
...
...
@@ -99,86 +99,16 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
}
EXPORT_SYMBOL_GPL
(
iwl_poll_bit
);
int
iwl_grab_nic_access_silent
(
struct
iwl_trans
*
trans
)
{
int
ret
;
lockdep_assert_held
(
&
trans
->
reg_lock
);
/* this bit wakes up the NIC */
__iwl_set_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
/*
* These bits say the device is running, and should keep running for
* at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
* but they do not indicate that embedded SRAM is restored yet;
* 3945 and 4965 have volatile SRAM, and must save/restore contents
* to/from host DRAM when sleeping/waking for power-saving.
* Each direction takes approximately 1/4 millisecond; with this
* overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
* series of register accesses are expected (e.g. reading Event Log),
* to keep device from sleeping.
*
* CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
* SRAM is okay/restored. We don't check that here because this call
* is just for hardware register access; but GP1 MAC_SLEEP check is a
* good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
*
* 5000 series and later (including 1000 series) have non-volatile SRAM,
* and do not save/restore SRAM when power cycling.
*/
ret
=
iwl_poll_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN
,
(
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
|
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP
),
15000
);
if
(
ret
<
0
)
{
iwl_write32
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_FORCE_NMI
);
return
-
EIO
;
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
iwl_grab_nic_access_silent
);
bool
iwl_grab_nic_access
(
struct
iwl_trans
*
trans
)
{
int
ret
=
iwl_grab_nic_access_silent
(
trans
);
if
(
unlikely
(
ret
))
{
u32
val
=
iwl_read32
(
trans
,
CSR_GP_CNTRL
);
WARN_ONCE
(
1
,
"Timeout waiting for hardware access "
"(CSR_GP_CNTRL 0x%08x)
\n
"
,
val
);
return
false
;
}
return
true
;
}
EXPORT_SYMBOL_GPL
(
iwl_grab_nic_access
);
void
iwl_release_nic_access
(
struct
iwl_trans
*
trans
)
{
lockdep_assert_held
(
&
trans
->
reg_lock
);
__iwl_clear_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
/*
* Above we read the CSR_GP_CNTRL register, which will flush
* any previous writes, but we need the write that clears the
* MAC_ACCESS_REQ bit to be performed before any other writes
* scheduled on different CPUs (after we drop reg_lock).
*/
mmiowb
();
}
EXPORT_SYMBOL_GPL
(
iwl_release_nic_access
);
u32
iwl_read_direct32
(
struct
iwl_trans
*
trans
,
u32
reg
)
{
u32
value
;
u32
value
=
0x5a5a5a5a
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
iwl_grab_nic_access
(
trans
);
value
=
iwl_read32
(
trans
,
reg
);
iwl_release_nic_access
(
trans
);
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
value
=
iwl_read32
(
trans
,
reg
);
iwl_trans_release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
return
value
;
...
...
@@ -190,9 +120,9 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
unsigned
long
flags
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
trans
)
))
{
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
iwl_write32
(
trans
,
reg
,
value
);
iwl_release_nic_access
(
trans
);
iwl_
trans_
release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
...
...
@@ -230,12 +160,13 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
u32
iwl_read_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
)
{
unsigned
long
flags
;
u32
val
;
u32
val
=
0x5a5a5a5a
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
iwl_grab_nic_access
(
trans
);
val
=
__iwl_read_prph
(
trans
,
ofs
);
iwl_release_nic_access
(
trans
);
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
val
=
__iwl_read_prph
(
trans
,
ofs
);
iwl_trans_release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
return
val
;
}
...
...
@@ -246,9 +177,9 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
unsigned
long
flags
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
trans
)
))
{
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
__iwl_write_prph
(
trans
,
ofs
,
val
);
iwl_release_nic_access
(
trans
);
iwl_
trans_
release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
...
...
@@ -259,10 +190,10 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
unsigned
long
flags
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
trans
)
))
{
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
__iwl_write_prph
(
trans
,
ofs
,
__iwl_read_prph
(
trans
,
ofs
)
|
mask
);
iwl_release_nic_access
(
trans
);
iwl_
trans_
release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
...
...
@@ -274,10 +205,10 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
unsigned
long
flags
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
trans
)
))
{
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
__iwl_write_prph
(
trans
,
ofs
,
(
__iwl_read_prph
(
trans
,
ofs
)
&
mask
)
|
bits
);
iwl_release_nic_access
(
trans
);
iwl_
trans_
release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
...
...
@@ -289,66 +220,11 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
u32
val
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
trans
)
))
{
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
val
=
__iwl_read_prph
(
trans
,
ofs
);
__iwl_write_prph
(
trans
,
ofs
,
(
val
&
~
mask
));
iwl_release_nic_access
(
trans
);
iwl_
trans_
release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
iwl_clear_bits_prph
);
void
_iwl_read_targ_mem_dwords
(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
)
{
unsigned
long
flags
;
int
offs
;
u32
*
vals
=
buf
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
trans
)))
{
iwl_write32
(
trans
,
HBUS_TARG_MEM_RADDR
,
addr
);
for
(
offs
=
0
;
offs
<
dwords
;
offs
++
)
vals
[
offs
]
=
iwl_read32
(
trans
,
HBUS_TARG_MEM_RDAT
);
iwl_release_nic_access
(
trans
);
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
_iwl_read_targ_mem_dwords
);
u32
iwl_read_targ_mem
(
struct
iwl_trans
*
trans
,
u32
addr
)
{
u32
value
;
_iwl_read_targ_mem_dwords
(
trans
,
addr
,
&
value
,
1
);
return
value
;
}
EXPORT_SYMBOL_GPL
(
iwl_read_targ_mem
);
int
_iwl_write_targ_mem_dwords
(
struct
iwl_trans
*
trans
,
u32
addr
,
const
void
*
buf
,
int
dwords
)
{
unsigned
long
flags
;
int
offs
,
result
=
0
;
const
u32
*
vals
=
buf
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
likely
(
iwl_grab_nic_access
(
trans
)))
{
iwl_write32
(
trans
,
HBUS_TARG_MEM_WADDR
,
addr
);
for
(
offs
=
0
;
offs
<
dwords
;
offs
++
)
iwl_write32
(
trans
,
HBUS_TARG_MEM_WDAT
,
vals
[
offs
]);
iwl_release_nic_access
(
trans
);
}
else
result
=
-
EBUSY
;
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
return
result
;
}
EXPORT_SYMBOL_GPL
(
_iwl_write_targ_mem_dwords
);
int
iwl_write_targ_mem
(
struct
iwl_trans
*
trans
,
u32
addr
,
u32
val
)
{
return
_iwl_write_targ_mem_dwords
(
trans
,
addr
,
&
val
,
1
);
}
EXPORT_SYMBOL_GPL
(
iwl_write_targ_mem
);
drivers/net/wireless/iwlwifi/iwl-io.h
浏览文件 @
48c6cc04
...
...
@@ -53,6 +53,8 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs)
void
iwl_set_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
);
void
iwl_clear_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
);
void
__iwl_set_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
);
void
__iwl_clear_bit
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
);
void
iwl_set_bits_mask
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
mask
,
u32
value
);
...
...
@@ -61,10 +63,6 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
int
iwl_poll_direct_bit
(
struct
iwl_trans
*
trans
,
u32
addr
,
u32
mask
,
int
timeout
);
int
iwl_grab_nic_access_silent
(
struct
iwl_trans
*
trans
);
bool
iwl_grab_nic_access
(
struct
iwl_trans
*
trans
);
void
iwl_release_nic_access
(
struct
iwl_trans
*
trans
);
u32
iwl_read_direct32
(
struct
iwl_trans
*
trans
,
u32
reg
);
void
iwl_write_direct32
(
struct
iwl_trans
*
trans
,
u32
reg
,
u32
value
);
...
...
@@ -76,19 +74,4 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
u32
bits
,
u32
mask
);
void
iwl_clear_bits_prph
(
struct
iwl_trans
*
trans
,
u32
ofs
,
u32
mask
);
void
_iwl_read_targ_mem_dwords
(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
);
#define iwl_read_targ_mem_bytes(trans, addr, buf, bufsize) \
do { \
BUILD_BUG_ON((bufsize) % sizeof(u32)); \
_iwl_read_targ_mem_dwords(trans, addr, buf, \
(bufsize) / sizeof(u32));\
} while (0)
int
_iwl_write_targ_mem_dwords
(
struct
iwl_trans
*
trans
,
u32
addr
,
const
void
*
buf
,
int
dwords
);
u32
iwl_read_targ_mem
(
struct
iwl_trans
*
trans
,
u32
addr
);
int
iwl_write_targ_mem
(
struct
iwl_trans
*
trans
,
u32
addr
,
u32
val
);
#endif
drivers/net/wireless/iwlwifi/iwl-test.c
浏览文件 @
48c6cc04
...
...
@@ -467,18 +467,20 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
if
(
IWL_ABS_PRPH_START
<=
addr
&&
addr
<
IWL_ABS_PRPH_START
+
PRPH_END
)
{
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
iwl_grab_nic_access
(
trans
);
if
(
!
iwl_trans_grab_nic_access
(
trans
,
false
))
{
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
return
-
EIO
;
}
iwl_write32
(
trans
,
HBUS_TARG_PRPH_RADDR
,
addr
|
(
3
<<
24
));
for
(
i
=
0
;
i
<
size
;
i
+=
4
)
*
(
u32
*
)(
tst
->
mem
.
addr
+
i
)
=
iwl_read32
(
trans
,
HBUS_TARG_PRPH_RDAT
);
iwl_release_nic_access
(
trans
);
iwl_
trans_
release_nic_access
(
trans
);
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
else
{
/* target memory (SRAM) */
_iwl_read_targ_mem_dwords
(
trans
,
addr
,
tst
->
mem
.
addr
,
tst
->
mem
.
size
/
4
);
iwl_trans_read_mem
(
trans
,
addr
,
tst
->
mem
.
addr
,
tst
->
mem
.
size
/
4
);
}
tst
->
mem
.
nchunks
=
...
...
@@ -501,28 +503,31 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
if
(
IWL_ABS_PRPH_START
<=
addr
&&
addr
<
IWL_ABS_PRPH_START
+
PRPH_END
)
{
/* Periphery writes can be 1-3 bytes long, or DWORDs */
if
(
size
<
4
)
{
memcpy
(
&
val
,
buf
,
size
);
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
iwl_grab_nic_access
(
trans
);
iwl_write32
(
trans
,
HBUS_TARG_PRPH_WADDR
,
(
addr
&
0x0000FFFF
)
|
((
size
-
1
)
<<
24
));
iwl_write32
(
trans
,
HBUS_TARG_PRPH_WDAT
,
val
);
iwl_release_nic_access
(
trans
);
/* needed after consecutive writes w/o read */
mmiowb
();
/* Periphery writes can be 1-3 bytes long, or DWORDs */
if
(
size
<
4
)
{
memcpy
(
&
val
,
buf
,
size
);
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
!
iwl_trans_grab_nic_access
(
trans
,
false
))
{
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
else
{
if
(
size
%
4
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
size
;
i
+=
4
)
iwl_write_prph
(
trans
,
addr
+
i
,
*
(
u32
*
)(
buf
+
i
));
return
-
EIO
;
}
iwl_write32
(
trans
,
HBUS_TARG_PRPH_WADDR
,
(
addr
&
0x0000FFFF
)
|
((
size
-
1
)
<<
24
));
iwl_write32
(
trans
,
HBUS_TARG_PRPH_WDAT
,
val
);
iwl_trans_release_nic_access
(
trans
);
/* needed after consecutive writes w/o read */
mmiowb
();
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
}
else
{
if
(
size
%
4
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
size
;
i
+=
4
)
iwl_write_prph
(
trans
,
addr
+
i
,
*
(
u32
*
)(
buf
+
i
));
}
}
else
if
(
iwl_test_valid_hw_addr
(
tst
,
addr
))
{
_iwl_write_targ_mem_dwords
(
trans
,
addr
,
buf
,
size
/
4
);
iwl_trans_write_mem
(
trans
,
addr
,
buf
,
size
/
4
);
}
else
{
return
-
EINVAL
;
}
...
...
drivers/net/wireless/iwlwifi/iwl-trans.h
浏览文件 @
48c6cc04
...
...
@@ -321,6 +321,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
* @n_no_reclaim_cmds: # of commands in list
* @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs,
* if unset 4k will be the RX buffer size
* @bc_table_dword: set to true if the BC table expects the byte count to be
* in DWORD (as opposed to bytes)
* @queue_watchdog_timeout: time (in ms) after which queues
* are considered stuck and will trigger device restart
* @command_names: array of command names, must be 256 entries
...
...
@@ -335,6 +337,7 @@ struct iwl_trans_config {
int
n_no_reclaim_cmds
;
bool
rx_buf_size_8k
;
bool
bc_table_dword
;
unsigned
int
queue_watchdog_timeout
;
const
char
**
command_names
;
};
...
...
@@ -387,16 +390,21 @@ struct iwl_trans;
* @read32: read a u32 register at offset ofs from the BAR
* @read_prph: read a DWORD from a periphery register
* @write_prph: write a DWORD to a periphery register
* @read_mem: read device's SRAM in DWORD
* @write_mem: write device's SRAM in DWORD
* @configure: configure parameters required by the transport layer from
* the op_mode. May be called several times before start_fw, can't be
* called after that.
* @set_pmi: set the power pmi state
* @grab_nic_access: wake the NIC to be able to access non-HBUS regs
* @release_nic_access: let the NIC go to sleep
*/
struct
iwl_trans_ops
{
int
(
*
start_hw
)(
struct
iwl_trans
*
iwl_trans
);
void
(
*
stop_hw
)(
struct
iwl_trans
*
iwl_trans
,
bool
op_mode_leaving
);
int
(
*
start_fw
)(
struct
iwl_trans
*
trans
,
const
struct
fw_img
*
fw
);
int
(
*
start_fw
)(
struct
iwl_trans
*
trans
,
const
struct
fw_img
*
fw
,
bool
run_in_rfkill
);
void
(
*
fw_alive
)(
struct
iwl_trans
*
trans
,
u32
scd_addr
);
void
(
*
stop_device
)(
struct
iwl_trans
*
trans
);
...
...
@@ -424,9 +432,15 @@ struct iwl_trans_ops {
u32
(
*
read32
)(
struct
iwl_trans
*
trans
,
u32
ofs
);
u32
(
*
read_prph
)(
struct
iwl_trans
*
trans
,
u32
ofs
);
void
(
*
write_prph
)(
struct
iwl_trans
*
trans
,
u32
ofs
,
u32
val
);
int
(
*
read_mem
)(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
);
int
(
*
write_mem
)(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
);
void
(
*
configure
)(
struct
iwl_trans
*
trans
,
const
struct
iwl_trans_config
*
trans_cfg
);
void
(
*
set_pmi
)(
struct
iwl_trans
*
trans
,
bool
state
);
bool
(
*
grab_nic_access
)(
struct
iwl_trans
*
trans
,
bool
silent
);
void
(
*
release_nic_access
)(
struct
iwl_trans
*
trans
);
};
/**
...
...
@@ -528,13 +542,14 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr)
}
static
inline
int
iwl_trans_start_fw
(
struct
iwl_trans
*
trans
,
const
struct
fw_img
*
fw
)
const
struct
fw_img
*
fw
,
bool
run_in_rfkill
)
{
might_sleep
();
WARN_ON_ONCE
(
!
trans
->
rx_mpdu_cmd
);
return
trans
->
ops
->
start_fw
(
trans
,
fw
);
return
trans
->
ops
->
start_fw
(
trans
,
fw
,
run_in_rfkill
);
}
static
inline
void
iwl_trans_stop_device
(
struct
iwl_trans
*
trans
)
...
...
@@ -636,7 +651,7 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
}
static
inline
int
iwl_trans_dbgfs_register
(
struct
iwl_trans
*
trans
,
struct
dentry
*
dir
)
struct
dentry
*
dir
)
{
return
trans
->
ops
->
dbgfs_register
(
trans
,
dir
);
}
...
...
@@ -679,11 +694,57 @@ static inline void iwl_trans_write_prph(struct iwl_trans *trans, u32 ofs,
return
trans
->
ops
->
write_prph
(
trans
,
ofs
,
val
);
}
static
inline
int
iwl_trans_read_mem
(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
)
{
return
trans
->
ops
->
read_mem
(
trans
,
addr
,
buf
,
dwords
);
}
#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \
do { \
if (__builtin_constant_p(bufsize)) \
BUILD_BUG_ON((bufsize) % sizeof(u32)); \
iwl_trans_read_mem(trans, addr, buf, (bufsize) / sizeof(u32));\
} while (0)
static
inline
u32
iwl_trans_read_mem32
(
struct
iwl_trans
*
trans
,
u32
addr
)
{
u32
value
;
if
(
WARN_ON
(
iwl_trans_read_mem
(
trans
,
addr
,
&
value
,
1
)))
return
0xa5a5a5a5
;
return
value
;
}
static
inline
int
iwl_trans_write_mem
(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
)
{
return
trans
->
ops
->
write_mem
(
trans
,
addr
,
buf
,
dwords
);
}
static
inline
u32
iwl_trans_write_mem32
(
struct
iwl_trans
*
trans
,
u32
addr
,
u32
val
)
{
return
iwl_trans_write_mem
(
trans
,
addr
,
&
val
,
1
);
}
static
inline
void
iwl_trans_set_pmi
(
struct
iwl_trans
*
trans
,
bool
state
)
{
trans
->
ops
->
set_pmi
(
trans
,
state
);
}
#define iwl_trans_grab_nic_access(trans, silent) \
__cond_lock(nic_access, \
likely((trans)->ops->grab_nic_access(trans, silent)))
static
inline
void
__releases
(
nic_access
)
iwl_trans_release_nic_access
(
struct
iwl_trans
*
trans
)
{
trans
->
ops
->
release_nic_access
(
trans
);
__release
(
nic_access
);
}
/*****************************************************
* driver (transport) register/unregister functions
******************************************************/
...
...
drivers/net/wireless/iwlwifi/pcie/internal.h
浏览文件 @
48c6cc04
...
...
@@ -222,8 +222,6 @@ struct iwl_txq {
* @rx_replenish: work that will be called when buffers need to be allocated
* @drv - pointer to iwl_drv
* @trans: pointer to the generic transport area
* @irq - the irq number for the device
* @irq_requested: true when the irq has been requested
* @scd_base_addr: scheduler sram base address in SRAM
* @scd_bc_tbls: pointer to the byte count table of the scheduler
* @kw: keep warm address
...
...
@@ -234,6 +232,7 @@ struct iwl_txq {
* @status - transport specific status flags
* @cmd_queue - command queue number
* @rx_buf_size_8k: 8 kB RX buffer size
* @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
* @rx_page_order: page order for receive buffer size
* @wd_timeout: queue watchdog timeout (jiffies)
*/
...
...
@@ -249,11 +248,9 @@ struct iwl_trans_pcie {
int
ict_index
;
u32
inta
;
bool
use_ict
;
bool
irq_requested
;
struct
tasklet_struct
irq_tasklet
;
struct
isr_statistics
isr_stats
;
unsigned
int
irq
;
spinlock_t
irq_lock
;
u32
inta_mask
;
u32
scd_base_addr
;
...
...
@@ -279,6 +276,7 @@ struct iwl_trans_pcie {
u8
no_reclaim_cmds
[
MAX_NO_RECLAIM_CMDS
];
bool
rx_buf_size_8k
;
bool
bc_table_dword
;
u32
rx_page_order
;
const
char
**
command_names
;
...
...
drivers/net/wireless/iwlwifi/pcie/rx.c
浏览文件 @
48c6cc04
...
...
@@ -545,6 +545,8 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
return
;
}
cancel_work_sync
(
&
trans_pcie
->
rx_replenish
);
spin_lock_irqsave
(
&
rxq
->
lock
,
flags
);
iwl_pcie_rxq_free_rbs
(
trans
);
spin_unlock_irqrestore
(
&
rxq
->
lock
,
flags
);
...
...
drivers/net/wireless/iwlwifi/pcie/trans.c
浏览文件 @
48c6cc04
...
...
@@ -435,7 +435,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
}
static
int
iwl_trans_pcie_start_fw
(
struct
iwl_trans
*
trans
,
const
struct
fw_img
*
fw
)
const
struct
fw_img
*
fw
,
bool
run_in_rfkill
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
int
ret
;
...
...
@@ -454,7 +454,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
/* If platform's RF_KILL switch is NOT set to KILL */
hw_rfkill
=
iwl_is_rfkill_set
(
trans
);
iwl_op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
if
(
hw_rfkill
)
if
(
hw_rfkill
&&
!
run_in_rfkill
)
return
-
ERFKILL
;
iwl_write32
(
trans
,
CSR_INT
,
0xFFFFFFFF
);
...
...
@@ -534,12 +534,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
iwl_enable_rfkill_int
(
trans
);
/* wait to make sure we flush pending tasklet*/
synchronize_irq
(
trans_pcie
->
irq
);
tasklet_kill
(
&
trans_pcie
->
irq_tasklet
);
cancel_work_sync
(
&
trans_pcie
->
rx_replenish
);
/* stop and reset the on-board processor */
iwl_write32
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_NEVO_RESET
);
...
...
@@ -564,33 +558,13 @@ static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans)
static
int
iwl_trans_pcie_start_hw
(
struct
iwl_trans
*
trans
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
int
err
;
bool
hw_rfkill
;
trans_pcie
->
inta_mask
=
CSR_INI_SET_MASK
;
if
(
!
trans_pcie
->
irq_requested
)
{
tasklet_init
(
&
trans_pcie
->
irq_tasklet
,
(
void
(
*
)(
unsigned
long
))
iwl_pcie_tasklet
,
(
unsigned
long
)
trans
);
iwl_pcie_alloc_ict
(
trans
);
err
=
request_irq
(
trans_pcie
->
irq
,
iwl_pcie_isr_ict
,
IRQF_SHARED
,
DRV_NAME
,
trans
);
if
(
err
)
{
IWL_ERR
(
trans
,
"Error allocating IRQ %d
\n
"
,
trans_pcie
->
irq
);
goto
error
;
}
trans_pcie
->
irq_requested
=
true
;
}
int
err
;
err
=
iwl_pcie_prepare_card_hw
(
trans
);
if
(
err
)
{
IWL_ERR
(
trans
,
"Error while preparing HW: %d
\n
"
,
err
);
goto
err_free_irq
;
return
err
;
}
iwl_pcie_apm_init
(
trans
);
...
...
@@ -601,15 +575,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
hw_rfkill
=
iwl_is_rfkill_set
(
trans
);
iwl_op_mode_hw_rf_kill
(
trans
->
op_mode
,
hw_rfkill
);
return
err
;
err_free_irq:
trans_pcie
->
irq_requested
=
false
;
free_irq
(
trans_pcie
->
irq
,
trans
);
error:
iwl_pcie_free_ict
(
trans
);
tasklet_kill
(
&
trans_pcie
->
irq_tasklet
);
return
err
;
return
0
;
}
static
void
iwl_trans_pcie_stop_hw
(
struct
iwl_trans
*
trans
,
...
...
@@ -703,19 +669,21 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
msecs_to_jiffies
(
trans_cfg
->
queue_watchdog_timeout
);
trans_pcie
->
command_names
=
trans_cfg
->
command_names
;
trans_pcie
->
bc_table_dword
=
trans_cfg
->
bc_table_dword
;
}
void
iwl_trans_pcie_free
(
struct
iwl_trans
*
trans
)
{
struct
iwl_trans_pcie
*
trans_pcie
=
IWL_TRANS_GET_PCIE_TRANS
(
trans
);
synchronize_irq
(
trans_pcie
->
pci_dev
->
irq
);
tasklet_kill
(
&
trans_pcie
->
irq_tasklet
);
iwl_pcie_tx_free
(
trans
);
iwl_pcie_rx_free
(
trans
);
if
(
trans_pcie
->
irq_requested
==
true
)
{
free_irq
(
trans_pcie
->
irq
,
trans
);
iwl_pcie_free_ict
(
trans
);
}
free_irq
(
trans_pcie
->
pci_dev
->
irq
,
trans
);
iwl_pcie_free_ict
(
trans
);
pci_disable_msi
(
trans_pcie
->
pci_dev
);
iounmap
(
trans_pcie
->
hw_base
);
...
...
@@ -758,6 +726,107 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
}
#endif
/* CONFIG_PM_SLEEP */
static
bool
iwl_trans_pcie_grab_nic_access
(
struct
iwl_trans
*
trans
,
bool
silent
)
{
int
ret
;
lockdep_assert_held
(
&
trans
->
reg_lock
);
/* this bit wakes up the NIC */
__iwl_set_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
/*
* These bits say the device is running, and should keep running for
* at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
* but they do not indicate that embedded SRAM is restored yet;
* 3945 and 4965 have volatile SRAM, and must save/restore contents
* to/from host DRAM when sleeping/waking for power-saving.
* Each direction takes approximately 1/4 millisecond; with this
* overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
* series of register accesses are expected (e.g. reading Event Log),
* to keep device from sleeping.
*
* CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
* SRAM is okay/restored. We don't check that here because this call
* is just for hardware register access; but GP1 MAC_SLEEP check is a
* good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
*
* 5000 series and later (including 1000 series) have non-volatile SRAM,
* and do not save/restore SRAM when power cycling.
*/
ret
=
iwl_poll_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN
,
(
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
|
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP
),
15000
);
if
(
unlikely
(
ret
<
0
))
{
iwl_write32
(
trans
,
CSR_RESET
,
CSR_RESET_REG_FLAG_FORCE_NMI
);
if
(
!
silent
)
{
u32
val
=
iwl_read32
(
trans
,
CSR_GP_CNTRL
);
WARN_ONCE
(
1
,
"Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)
\n
"
,
val
);
return
false
;
}
}
return
true
;
}
static
void
iwl_trans_pcie_release_nic_access
(
struct
iwl_trans
*
trans
)
{
lockdep_assert_held
(
&
trans
->
reg_lock
);
__iwl_clear_bit
(
trans
,
CSR_GP_CNTRL
,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ
);
/*
* Above we read the CSR_GP_CNTRL register, which will flush
* any previous writes, but we need the write that clears the
* MAC_ACCESS_REQ bit to be performed before any other writes
* scheduled on different CPUs (after we drop reg_lock).
*/
mmiowb
();
}
static
int
iwl_trans_pcie_read_mem
(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
)
{
unsigned
long
flags
;
int
offs
,
ret
=
0
;
u32
*
vals
=
buf
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
iwl_write32
(
trans
,
HBUS_TARG_MEM_RADDR
,
addr
);
for
(
offs
=
0
;
offs
<
dwords
;
offs
++
)
vals
[
offs
]
=
iwl_read32
(
trans
,
HBUS_TARG_MEM_RDAT
);
iwl_trans_release_nic_access
(
trans
);
}
else
{
ret
=
-
EBUSY
;
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
return
ret
;
}
static
int
iwl_trans_pcie_write_mem
(
struct
iwl_trans
*
trans
,
u32
addr
,
void
*
buf
,
int
dwords
)
{
unsigned
long
flags
;
int
offs
,
ret
=
0
;
u32
*
vals
=
buf
;
spin_lock_irqsave
(
&
trans
->
reg_lock
,
flags
);
if
(
iwl_trans_grab_nic_access
(
trans
,
false
))
{
iwl_write32
(
trans
,
HBUS_TARG_MEM_WADDR
,
addr
);
for
(
offs
=
0
;
offs
<
dwords
;
offs
++
)
iwl_write32
(
trans
,
HBUS_TARG_MEM_WDAT
,
vals
[
offs
]);
iwl_trans_release_nic_access
(
trans
);
}
else
{
ret
=
-
EBUSY
;
}
spin_unlock_irqrestore
(
&
trans
->
reg_lock
,
flags
);
return
ret
;
}
#define IWL_FLUSH_WAIT_MS 2000
static
int
iwl_trans_pcie_wait_txq_empty
(
struct
iwl_trans
*
trans
)
...
...
@@ -1235,8 +1304,12 @@ static const struct iwl_trans_ops trans_ops_pcie = {
.
read32
=
iwl_trans_pcie_read32
,
.
read_prph
=
iwl_trans_pcie_read_prph
,
.
write_prph
=
iwl_trans_pcie_write_prph
,
.
read_mem
=
iwl_trans_pcie_read_mem
,
.
write_mem
=
iwl_trans_pcie_write_mem
,
.
configure
=
iwl_trans_pcie_configure
,
.
set_pmi
=
iwl_trans_pcie_set_pmi
,
.
grab_nic_access
=
iwl_trans_pcie_grab_nic_access
,
.
release_nic_access
=
iwl_trans_pcie_release_nic_access
};
struct
iwl_trans
*
iwl_trans_pcie_alloc
(
struct
pci_dev
*
pdev
,
...
...
@@ -1318,7 +1391,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
}
trans
->
dev
=
&
pdev
->
dev
;
trans_pcie
->
irq
=
pdev
->
irq
;
trans_pcie
->
pci_dev
=
pdev
;
trans
->
hw_rev
=
iwl_read32
(
trans
,
CSR_HW_REV
);
trans
->
hw_id
=
(
pdev
->
device
<<
16
)
+
pdev
->
subsystem_device
;
...
...
@@ -1344,8 +1416,27 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
if
(
!
trans
->
dev_cmd_pool
)
goto
out_pci_disable_msi
;
trans_pcie
->
inta_mask
=
CSR_INI_SET_MASK
;
tasklet_init
(
&
trans_pcie
->
irq_tasklet
,
(
void
(
*
)(
unsigned
long
))
iwl_pcie_tasklet
,
(
unsigned
long
)
trans
);
if
(
iwl_pcie_alloc_ict
(
trans
))
goto
out_free_cmd_pool
;
err
=
request_irq
(
pdev
->
irq
,
iwl_pcie_isr_ict
,
IRQF_SHARED
,
DRV_NAME
,
trans
);
if
(
err
)
{
IWL_ERR
(
trans
,
"Error allocating IRQ %d
\n
"
,
pdev
->
irq
);
goto
out_free_ict
;
}
return
trans
;
out_free_ict:
iwl_pcie_free_ict
(
trans
);
out_free_cmd_pool:
kmem_cache_destroy
(
trans
->
dev_cmd_pool
);
out_pci_disable_msi:
pci_disable_msi
(
pdev
);
out_pci_release_regions:
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
浏览文件 @
48c6cc04
...
...
@@ -160,7 +160,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
IWL_ERR
(
trans
,
"Current SW read_ptr %d write_ptr %d
\n
"
,
txq
->
q
.
read_ptr
,
txq
->
q
.
write_ptr
);
iwl_
read_targ
_mem_bytes
(
trans
,
scd_sram_addr
,
buf
,
sizeof
(
buf
));
iwl_
trans_read
_mem_bytes
(
trans
,
scd_sram_addr
,
buf
,
sizeof
(
buf
));
iwl_print_hex_error
(
trans
,
buf
,
sizeof
(
buf
));
...
...
@@ -173,9 +173,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
u8
fifo
=
(
status
>>
SCD_QUEUE_STTS_REG_POS_TXF
)
&
0x7
;
bool
active
=
!!
(
status
&
BIT
(
SCD_QUEUE_STTS_REG_POS_ACTIVE
));
u32
tbl_dw
=
iwl_
read_targ_mem
(
trans
,
trans_pcie
->
scd_base_addr
+
SCD_TRANS_TBL_OFFSET_QUEUE
(
i
));
iwl_
trans_read_mem32
(
trans
,
trans_pcie
->
scd_base_addr
+
SCD_TRANS_TBL_OFFSET_QUEUE
(
i
));
if
(
i
&
0x1
)
tbl_dw
=
(
tbl_dw
&
0xFFFF0000
)
>>
16
;
...
...
@@ -237,7 +237,10 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
break
;
}
bc_ent
=
cpu_to_le16
((
len
&
0xFFF
)
|
(
sta_id
<<
12
));
if
(
trans_pcie
->
bc_table_dword
)
len
=
DIV_ROUND_UP
(
len
,
4
);
bc_ent
=
cpu_to_le16
(
len
|
(
sta_id
<<
12
));
scd_bc_tbl
[
txq_id
].
tfd_offset
[
write_ptr
]
=
bc_ent
;
...
...
@@ -656,16 +659,16 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
/* reset conext data memory */
for
(;
a
<
trans_pcie
->
scd_base_addr
+
SCD_CONTEXT_MEM_UPPER_BOUND
;
a
+=
4
)
iwl_
write_targ_mem
(
trans
,
a
,
0
);
iwl_
trans_write_mem32
(
trans
,
a
,
0
);
/* reset tx status memory */
for
(;
a
<
trans_pcie
->
scd_base_addr
+
SCD_TX_STTS_MEM_UPPER_BOUND
;
a
+=
4
)
iwl_
write_targ_mem
(
trans
,
a
,
0
);
iwl_
trans_write_mem32
(
trans
,
a
,
0
);
for
(;
a
<
trans_pcie
->
scd_base_addr
+
SCD_TRANS_TBL_OFFSET_QUEUE
(
trans
->
cfg
->
base_params
->
num_of_queues
);
a
+=
4
)
iwl_
write_targ_mem
(
trans
,
a
,
0
);
iwl_
trans_write_mem32
(
trans
,
a
,
0
);
iwl_write_prph
(
trans
,
SCD_DRAM_BASE_ADDR
,
trans_pcie
->
scd_bc_tbls
.
dma
>>
10
);
...
...
@@ -1002,14 +1005,14 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
tbl_dw_addr
=
trans_pcie
->
scd_base_addr
+
SCD_TRANS_TBL_OFFSET_QUEUE
(
txq_id
);
tbl_dw
=
iwl_
read_targ_mem
(
trans
,
tbl_dw_addr
);
tbl_dw
=
iwl_
trans_read_mem32
(
trans
,
tbl_dw_addr
);
if
(
txq_id
&
0x1
)
tbl_dw
=
(
scd_q2ratid
<<
16
)
|
(
tbl_dw
&
0x0000FFFF
);
else
tbl_dw
=
scd_q2ratid
|
(
tbl_dw
&
0xFFFF0000
);
iwl_
write_targ_mem
(
trans
,
tbl_dw_addr
,
tbl_dw
);
iwl_
trans_write_mem32
(
trans
,
tbl_dw_addr
,
tbl_dw
);
return
0
;
}
...
...
@@ -1068,9 +1071,9 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
iwl_write_prph
(
trans
,
SCD_QUEUE_RDPTR
(
txq_id
),
ssn
);
/* Set up Tx window size and frame limit for this queue */
iwl_
write_targ_mem
(
trans
,
trans_pcie
->
scd_base_addr
+
iwl_
trans_write_mem32
(
trans
,
trans_pcie
->
scd_base_addr
+
SCD_CONTEXT_QUEUE_OFFSET
(
txq_id
),
0
);
iwl_
write_targ_mem
(
trans
,
trans_pcie
->
scd_base_addr
+
iwl_
trans_write_mem32
(
trans
,
trans_pcie
->
scd_base_addr
+
SCD_CONTEXT_QUEUE_OFFSET
(
txq_id
)
+
sizeof
(
u32
),
((
frame_limit
<<
SCD_QUEUE_CTX_REG2_WIN_SIZE_POS
)
&
SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK
)
|
...
...
@@ -1101,8 +1104,8 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
iwl_pcie_txq_set_inactive
(
trans
,
txq_id
);
_iwl_write_targ_mem_dwords
(
trans
,
stts_addr
,
zero_val
,
ARRAY_SIZE
(
zero_val
));
iwl_trans_write_mem
(
trans
,
stts_addr
,
(
void
*
)
zero_val
,
ARRAY_SIZE
(
zero_val
));
iwl_pcie_txq_unmap
(
trans
,
txq_id
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录