Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
acf0f100
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看板
提交
acf0f100
编写于
5月 29, 2005
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge of /home/davem/src/GIT/tg3-2.6/
上级
79158229
1b628151
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
556 addition
and
15 deletion
+556
-15
drivers/net/tg3.c
drivers/net/tg3.c
+556
-15
未找到文件。
drivers/net/tg3.c
浏览文件 @
acf0f100
...
...
@@ -133,6 +133,8 @@
/* number of ETHTOOL_GSTATS u64's */
#define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64))
#define TG3_NUM_TEST 6
static
char
version
[]
__devinitdata
=
DRV_MODULE_NAME
".c:v"
DRV_MODULE_VERSION
" ("
DRV_MODULE_RELDATE
")
\n
"
;
...
...
@@ -316,6 +318,17 @@ static struct {
{
"nic_tx_threshold_hit"
}
};
static
struct
{
const
char
string
[
ETH_GSTRING_LEN
];
}
ethtool_test_keys
[
TG3_NUM_TEST
]
=
{
{
"nvram test (online) "
},
{
"link test (online) "
},
{
"register test (offline)"
},
{
"memory test (offline)"
},
{
"loopback test (offline)"
},
{
"interrupt test (offline)"
},
};
static
void
tg3_write_indirect_reg32
(
struct
tg3
*
tp
,
u32
off
,
u32
val
)
{
if
((
tp
->
tg3_flags
&
TG3_FLAG_PCIX_TARGET_HWBUG
)
!=
0
)
{
...
...
@@ -3070,7 +3083,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
}
static
int
tg3_init_hw
(
struct
tg3
*
);
static
int
tg3_halt
(
struct
tg3
*
,
int
);
static
int
tg3_halt
(
struct
tg3
*
,
int
,
int
);
#ifdef CONFIG_NET_POLL_CONTROLLER
static
void
tg3_poll_controller
(
struct
net_device
*
dev
)
...
...
@@ -3094,7 +3107,7 @@ static void tg3_reset_task(void *_data)
restart_timer
=
tp
->
tg3_flags2
&
TG3_FLG2_RESTART_TIMER
;
tp
->
tg3_flags2
&=
~
TG3_FLG2_RESTART_TIMER
;
tg3_halt
(
tp
,
0
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
0
);
tg3_init_hw
(
tp
);
tg3_netif_start
(
tp
);
...
...
@@ -3440,7 +3453,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
spin_lock_irq
(
&
tp
->
lock
);
spin_lock
(
&
tp
->
tx_lock
);
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
tg3_set_mtu
(
dev
,
tp
,
new_mtu
);
...
...
@@ -4131,19 +4144,19 @@ static void tg3_stop_fw(struct tg3 *tp)
}
/* tp->lock is held. */
static
int
tg3_halt
(
struct
tg3
*
tp
,
int
silent
)
static
int
tg3_halt
(
struct
tg3
*
tp
,
int
kind
,
int
silent
)
{
int
err
;
tg3_stop_fw
(
tp
);
tg3_write_sig_pre_reset
(
tp
,
RESET_KIND_SHUTDOWN
);
tg3_write_sig_pre_reset
(
tp
,
kind
);
tg3_abort_hw
(
tp
,
silent
);
err
=
tg3_chip_reset
(
tp
);
tg3_write_sig_legacy
(
tp
,
RESET_KIND_SHUTDOWN
);
tg3_write_sig_post_reset
(
tp
,
RESET_KIND_SHUTDOWN
);
tg3_write_sig_legacy
(
tp
,
kind
);
tg3_write_sig_post_reset
(
tp
,
kind
);
if
(
err
)
return
err
;
...
...
@@ -4357,7 +4370,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
*/
tp
->
tg3_flags
|=
TG3_FLAG_PCIX_TARGET_HWBUG
;
/* It is possible that bootcode is still loading at this point.
* Get the nvram lock first before halting the cpu.
*/
tg3_nvram_lock
(
tp
);
err
=
tg3_halt_cpu
(
tp
,
cpu_base
);
tg3_nvram_unlock
(
tp
);
if
(
err
)
goto
out
;
...
...
@@ -5881,6 +5899,9 @@ static int tg3_test_interrupt(struct tg3 *tp)
int
err
,
i
;
u32
int_mbox
=
0
;
if
(
!
netif_running
(
dev
))
return
-
ENODEV
;
tg3_disable_ints
(
tp
);
free_irq
(
tp
->
pdev
->
irq
,
dev
);
...
...
@@ -5984,7 +6005,7 @@ static int tg3_test_msi(struct tg3 *tp)
spin_lock_irq
(
&
tp
->
lock
);
spin_lock
(
&
tp
->
tx_lock
);
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
err
=
tg3_init_hw
(
tp
);
spin_unlock
(
&
tp
->
tx_lock
);
...
...
@@ -6060,7 +6081,7 @@ static int tg3_open(struct net_device *dev)
err
=
tg3_init_hw
(
tp
);
if
(
err
)
{
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
tg3_free_rings
(
tp
);
}
else
{
if
(
tp
->
tg3_flags
&
TG3_FLAG_TAGGED_STATUS
)
...
...
@@ -6104,7 +6125,7 @@ static int tg3_open(struct net_device *dev)
pci_disable_msi
(
tp
->
pdev
);
tp
->
tg3_flags2
&=
~
TG3_FLG2_USING_MSI
;
}
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
tg3_free_rings
(
tp
);
tg3_free_consistent
(
tp
);
...
...
@@ -6377,7 +6398,7 @@ static int tg3_close(struct net_device *dev)
tg3_disable_ints
(
tp
);
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
tg3_free_rings
(
tp
);
tp
->
tg3_flags
&=
~
(
TG3_FLAG_INIT_COMPLETE
|
...
...
@@ -7097,7 +7118,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
tp
->
tx_pending
=
ering
->
tx_pending
;
if
(
netif_running
(
dev
))
{
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
tg3_init_hw
(
tp
);
tg3_netif_start
(
tp
);
}
...
...
@@ -7140,7 +7161,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
tp
->
tg3_flags
&=
~
TG3_FLAG_TX_PAUSE
;
if
(
netif_running
(
dev
))
{
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
tg3_init_hw
(
tp
);
tg3_netif_start
(
tp
);
}
...
...
@@ -7199,12 +7220,20 @@ static int tg3_get_stats_count (struct net_device *dev)
return
TG3_NUM_STATS
;
}
static
int
tg3_get_test_count
(
struct
net_device
*
dev
)
{
return
TG3_NUM_TEST
;
}
static
void
tg3_get_strings
(
struct
net_device
*
dev
,
u32
stringset
,
u8
*
buf
)
{
switch
(
stringset
)
{
case
ETH_SS_STATS
:
memcpy
(
buf
,
&
ethtool_stats_keys
,
sizeof
(
ethtool_stats_keys
));
break
;
case
ETH_SS_TEST
:
memcpy
(
buf
,
&
ethtool_test_keys
,
sizeof
(
ethtool_test_keys
));
break
;
default:
WARN_ON
(
1
);
/* we need a WARN() */
break
;
...
...
@@ -7218,6 +7247,516 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
memcpy
(
tmp_stats
,
tg3_get_estats
(
tp
),
sizeof
(
tp
->
estats
));
}
#define NVRAM_TEST_SIZE 0x100
static
int
tg3_test_nvram
(
struct
tg3
*
tp
)
{
u32
*
buf
,
csum
;
int
i
,
j
,
err
=
0
;
buf
=
kmalloc
(
NVRAM_TEST_SIZE
,
GFP_KERNEL
);
if
(
buf
==
NULL
)
return
-
ENOMEM
;
for
(
i
=
0
,
j
=
0
;
i
<
NVRAM_TEST_SIZE
;
i
+=
4
,
j
++
)
{
u32
val
;
if
((
err
=
tg3_nvram_read
(
tp
,
i
,
&
val
))
!=
0
)
break
;
buf
[
j
]
=
cpu_to_le32
(
val
);
}
if
(
i
<
NVRAM_TEST_SIZE
)
goto
out
;
err
=
-
EIO
;
if
(
cpu_to_be32
(
buf
[
0
])
!=
TG3_EEPROM_MAGIC
)
goto
out
;
/* Bootstrap checksum at offset 0x10 */
csum
=
calc_crc
((
unsigned
char
*
)
buf
,
0x10
);
if
(
csum
!=
cpu_to_le32
(
buf
[
0x10
/
4
]))
goto
out
;
/* Manufacturing block starts at offset 0x74, checksum at 0xfc */
csum
=
calc_crc
((
unsigned
char
*
)
&
buf
[
0x74
/
4
],
0x88
);
if
(
csum
!=
cpu_to_le32
(
buf
[
0xfc
/
4
]))
goto
out
;
err
=
0
;
out:
kfree
(
buf
);
return
err
;
}
#define TG3_SERDES_TIMEOUT_SEC 2
#define TG3_COPPER_TIMEOUT_SEC 6
static
int
tg3_test_link
(
struct
tg3
*
tp
)
{
int
i
,
max
;
if
(
!
netif_running
(
tp
->
dev
))
return
-
ENODEV
;
if
(
tp
->
tg3_flags2
&
TG3_FLG2_PHY_SERDES
)
max
=
TG3_SERDES_TIMEOUT_SEC
;
else
max
=
TG3_COPPER_TIMEOUT_SEC
;
for
(
i
=
0
;
i
<
max
;
i
++
)
{
if
(
netif_carrier_ok
(
tp
->
dev
))
return
0
;
if
(
msleep_interruptible
(
1000
))
break
;
}
return
-
EIO
;
}
/* Only test the commonly used registers */
static
int
tg3_test_registers
(
struct
tg3
*
tp
)
{
int
i
,
is_5705
;
u32
offset
,
read_mask
,
write_mask
,
val
,
save_val
,
read_val
;
static
struct
{
u16
offset
;
u16
flags
;
#define TG3_FL_5705 0x1
#define TG3_FL_NOT_5705 0x2
#define TG3_FL_NOT_5788 0x4
u32
read_mask
;
u32
write_mask
;
}
reg_tbl
[]
=
{
/* MAC Control Registers */
{
MAC_MODE
,
TG3_FL_NOT_5705
,
0x00000000
,
0x00ef6f8c
},
{
MAC_MODE
,
TG3_FL_5705
,
0x00000000
,
0x01ef6b8c
},
{
MAC_STATUS
,
TG3_FL_NOT_5705
,
0x03800107
,
0x00000000
},
{
MAC_STATUS
,
TG3_FL_5705
,
0x03800100
,
0x00000000
},
{
MAC_ADDR_0_HIGH
,
0x0000
,
0x00000000
,
0x0000ffff
},
{
MAC_ADDR_0_LOW
,
0x0000
,
0x00000000
,
0xffffffff
},
{
MAC_RX_MTU_SIZE
,
0x0000
,
0x00000000
,
0x0000ffff
},
{
MAC_TX_MODE
,
0x0000
,
0x00000000
,
0x00000070
},
{
MAC_TX_LENGTHS
,
0x0000
,
0x00000000
,
0x00003fff
},
{
MAC_RX_MODE
,
TG3_FL_NOT_5705
,
0x00000000
,
0x000007fc
},
{
MAC_RX_MODE
,
TG3_FL_5705
,
0x00000000
,
0x000007dc
},
{
MAC_HASH_REG_0
,
0x0000
,
0x00000000
,
0xffffffff
},
{
MAC_HASH_REG_1
,
0x0000
,
0x00000000
,
0xffffffff
},
{
MAC_HASH_REG_2
,
0x0000
,
0x00000000
,
0xffffffff
},
{
MAC_HASH_REG_3
,
0x0000
,
0x00000000
,
0xffffffff
},
/* Receive Data and Receive BD Initiator Control Registers. */
{
RCVDBDI_JUMBO_BD
+
0
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
RCVDBDI_JUMBO_BD
+
4
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
RCVDBDI_JUMBO_BD
+
8
,
TG3_FL_NOT_5705
,
0x00000000
,
0x00000003
},
{
RCVDBDI_JUMBO_BD
+
0xc
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
RCVDBDI_STD_BD
+
0
,
0x0000
,
0x00000000
,
0xffffffff
},
{
RCVDBDI_STD_BD
+
4
,
0x0000
,
0x00000000
,
0xffffffff
},
{
RCVDBDI_STD_BD
+
8
,
0x0000
,
0x00000000
,
0xffff0002
},
{
RCVDBDI_STD_BD
+
0xc
,
0x0000
,
0x00000000
,
0xffffffff
},
/* Receive BD Initiator Control Registers. */
{
RCVBDI_STD_THRESH
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
RCVBDI_STD_THRESH
,
TG3_FL_5705
,
0x00000000
,
0x000003ff
},
{
RCVBDI_JUMBO_THRESH
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
/* Host Coalescing Control Registers. */
{
HOSTCC_MODE
,
TG3_FL_NOT_5705
,
0x00000000
,
0x00000004
},
{
HOSTCC_MODE
,
TG3_FL_5705
,
0x00000000
,
0x000000f6
},
{
HOSTCC_RXCOL_TICKS
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_RXCOL_TICKS
,
TG3_FL_5705
,
0x00000000
,
0x000003ff
},
{
HOSTCC_TXCOL_TICKS
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_TXCOL_TICKS
,
TG3_FL_5705
,
0x00000000
,
0x000003ff
},
{
HOSTCC_RXMAX_FRAMES
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_RXMAX_FRAMES
,
TG3_FL_5705
|
TG3_FL_NOT_5788
,
0x00000000
,
0x000000ff
},
{
HOSTCC_TXMAX_FRAMES
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_TXMAX_FRAMES
,
TG3_FL_5705
|
TG3_FL_NOT_5788
,
0x00000000
,
0x000000ff
},
{
HOSTCC_RXCOAL_TICK_INT
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_TXCOAL_TICK_INT
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_RXCOAL_MAXF_INT
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_RXCOAL_MAXF_INT
,
TG3_FL_5705
|
TG3_FL_NOT_5788
,
0x00000000
,
0x000000ff
},
{
HOSTCC_TXCOAL_MAXF_INT
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_TXCOAL_MAXF_INT
,
TG3_FL_5705
|
TG3_FL_NOT_5788
,
0x00000000
,
0x000000ff
},
{
HOSTCC_STAT_COAL_TICKS
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_STATS_BLK_HOST_ADDR
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_STATS_BLK_HOST_ADDR
+
4
,
TG3_FL_NOT_5705
,
0x00000000
,
0xffffffff
},
{
HOSTCC_STATUS_BLK_HOST_ADDR
,
0x0000
,
0x00000000
,
0xffffffff
},
{
HOSTCC_STATUS_BLK_HOST_ADDR
+
4
,
0x0000
,
0x00000000
,
0xffffffff
},
{
HOSTCC_STATS_BLK_NIC_ADDR
,
0x0000
,
0xffffffff
,
0x00000000
},
{
HOSTCC_STATUS_BLK_NIC_ADDR
,
0x0000
,
0xffffffff
,
0x00000000
},
/* Buffer Manager Control Registers. */
{
BUFMGR_MB_POOL_ADDR
,
0x0000
,
0x00000000
,
0x007fff80
},
{
BUFMGR_MB_POOL_SIZE
,
0x0000
,
0x00000000
,
0x007fffff
},
{
BUFMGR_MB_RDMA_LOW_WATER
,
0x0000
,
0x00000000
,
0x0000003f
},
{
BUFMGR_MB_MACRX_LOW_WATER
,
0x0000
,
0x00000000
,
0x000001ff
},
{
BUFMGR_MB_HIGH_WATER
,
0x0000
,
0x00000000
,
0x000001ff
},
{
BUFMGR_DMA_DESC_POOL_ADDR
,
TG3_FL_NOT_5705
,
0xffffffff
,
0x00000000
},
{
BUFMGR_DMA_DESC_POOL_SIZE
,
TG3_FL_NOT_5705
,
0xffffffff
,
0x00000000
},
/* Mailbox Registers */
{
GRCMBOX_RCVSTD_PROD_IDX
+
4
,
0x0000
,
0x00000000
,
0x000001ff
},
{
GRCMBOX_RCVJUMBO_PROD_IDX
+
4
,
TG3_FL_NOT_5705
,
0x00000000
,
0x000001ff
},
{
GRCMBOX_RCVRET_CON_IDX_0
+
4
,
0x0000
,
0x00000000
,
0x000007ff
},
{
GRCMBOX_SNDHOST_PROD_IDX_0
+
4
,
0x0000
,
0x00000000
,
0x000001ff
},
{
0xffff
,
0x0000
,
0x00000000
,
0x00000000
},
};
if
(
tp
->
tg3_flags2
&
TG3_FLG2_5705_PLUS
)
is_5705
=
1
;
else
is_5705
=
0
;
for
(
i
=
0
;
reg_tbl
[
i
].
offset
!=
0xffff
;
i
++
)
{
if
(
is_5705
&&
(
reg_tbl
[
i
].
flags
&
TG3_FL_NOT_5705
))
continue
;
if
(
!
is_5705
&&
(
reg_tbl
[
i
].
flags
&
TG3_FL_5705
))
continue
;
if
((
tp
->
tg3_flags2
&
TG3_FLG2_IS_5788
)
&&
(
reg_tbl
[
i
].
flags
&
TG3_FL_NOT_5788
))
continue
;
offset
=
(
u32
)
reg_tbl
[
i
].
offset
;
read_mask
=
reg_tbl
[
i
].
read_mask
;
write_mask
=
reg_tbl
[
i
].
write_mask
;
/* Save the original register content */
save_val
=
tr32
(
offset
);
/* Determine the read-only value. */
read_val
=
save_val
&
read_mask
;
/* Write zero to the register, then make sure the read-only bits
* are not changed and the read/write bits are all zeros.
*/
tw32
(
offset
,
0
);
val
=
tr32
(
offset
);
/* Test the read-only and read/write bits. */
if
(((
val
&
read_mask
)
!=
read_val
)
||
(
val
&
write_mask
))
goto
out
;
/* Write ones to all the bits defined by RdMask and WrMask, then
* make sure the read-only bits are not changed and the
* read/write bits are all ones.
*/
tw32
(
offset
,
read_mask
|
write_mask
);
val
=
tr32
(
offset
);
/* Test the read-only bits. */
if
((
val
&
read_mask
)
!=
read_val
)
goto
out
;
/* Test the read/write bits. */
if
((
val
&
write_mask
)
!=
write_mask
)
goto
out
;
tw32
(
offset
,
save_val
);
}
return
0
;
out:
printk
(
KERN_ERR
PFX
"Register test failed at offset %x
\n
"
,
offset
);
tw32
(
offset
,
save_val
);
return
-
EIO
;
}
static
int
tg3_do_mem_test
(
struct
tg3
*
tp
,
u32
offset
,
u32
len
)
{
static
u32
test_pattern
[]
=
{
0x00000000
,
0xffffffff
,
0xaa55a55a
};
int
i
;
u32
j
;
for
(
i
=
0
;
i
<
sizeof
(
test_pattern
)
/
sizeof
(
u32
);
i
++
)
{
for
(
j
=
0
;
j
<
len
;
j
+=
4
)
{
u32
val
;
tg3_write_mem
(
tp
,
offset
+
j
,
test_pattern
[
i
]);
tg3_read_mem
(
tp
,
offset
+
j
,
&
val
);
if
(
val
!=
test_pattern
[
i
])
return
-
EIO
;
}
}
return
0
;
}
static
int
tg3_test_memory
(
struct
tg3
*
tp
)
{
static
struct
mem_entry
{
u32
offset
;
u32
len
;
}
mem_tbl_570x
[]
=
{
{
0x00000000
,
0x01000
},
{
0x00002000
,
0x1c000
},
{
0xffffffff
,
0x00000
}
},
mem_tbl_5705
[]
=
{
{
0x00000100
,
0x0000c
},
{
0x00000200
,
0x00008
},
{
0x00000b50
,
0x00400
},
{
0x00004000
,
0x00800
},
{
0x00006000
,
0x01000
},
{
0x00008000
,
0x02000
},
{
0x00010000
,
0x0e000
},
{
0xffffffff
,
0x00000
}
};
struct
mem_entry
*
mem_tbl
;
int
err
=
0
;
int
i
;
if
(
tp
->
tg3_flags2
&
TG3_FLG2_5705_PLUS
)
mem_tbl
=
mem_tbl_5705
;
else
mem_tbl
=
mem_tbl_570x
;
for
(
i
=
0
;
mem_tbl
[
i
].
offset
!=
0xffffffff
;
i
++
)
{
if
((
err
=
tg3_do_mem_test
(
tp
,
mem_tbl
[
i
].
offset
,
mem_tbl
[
i
].
len
))
!=
0
)
break
;
}
return
err
;
}
static
int
tg3_test_loopback
(
struct
tg3
*
tp
)
{
u32
mac_mode
,
send_idx
,
rx_start_idx
,
rx_idx
,
tx_idx
,
opaque_key
;
u32
desc_idx
;
struct
sk_buff
*
skb
,
*
rx_skb
;
u8
*
tx_data
;
dma_addr_t
map
;
int
num_pkts
,
tx_len
,
rx_len
,
i
,
err
;
struct
tg3_rx_buffer_desc
*
desc
;
if
(
!
netif_running
(
tp
->
dev
))
return
-
ENODEV
;
err
=
-
EIO
;
tg3_abort_hw
(
tp
,
1
);
/* Clearing this flag to keep interrupts disabled */
tp
->
tg3_flags
&=
~
TG3_FLAG_INIT_COMPLETE
;
tg3_reset_hw
(
tp
);
mac_mode
=
(
tp
->
mac_mode
&
~
MAC_MODE_PORT_MODE_MASK
)
|
MAC_MODE_PORT_INT_LPBACK
|
MAC_MODE_LINK_POLARITY
|
MAC_MODE_PORT_MODE_GMII
;
tw32
(
MAC_MODE
,
mac_mode
);
tx_len
=
1514
;
skb
=
dev_alloc_skb
(
tx_len
);
tx_data
=
skb_put
(
skb
,
tx_len
);
memcpy
(
tx_data
,
tp
->
dev
->
dev_addr
,
6
);
memset
(
tx_data
+
6
,
0x0
,
8
);
tw32
(
MAC_RX_MTU_SIZE
,
tx_len
+
4
);
for
(
i
=
14
;
i
<
tx_len
;
i
++
)
tx_data
[
i
]
=
(
u8
)
(
i
&
0xff
);
map
=
pci_map_single
(
tp
->
pdev
,
skb
->
data
,
tx_len
,
PCI_DMA_TODEVICE
);
tw32_f
(
HOSTCC_MODE
,
tp
->
coalesce_mode
|
HOSTCC_MODE_ENABLE
|
HOSTCC_MODE_NOW
);
udelay
(
10
);
rx_start_idx
=
tp
->
hw_status
->
idx
[
0
].
rx_producer
;
send_idx
=
0
;
num_pkts
=
0
;
tg3_set_txd
(
tp
,
send_idx
,
map
,
tx_len
,
0
,
1
);
send_idx
++
;
num_pkts
++
;
tw32_tx_mbox
(
MAILBOX_SNDHOST_PROD_IDX_0
+
TG3_64BIT_REG_LOW
,
send_idx
);
tr32
(
MAILBOX_SNDHOST_PROD_IDX_0
+
TG3_64BIT_REG_LOW
);
udelay
(
10
);
for
(
i
=
0
;
i
<
10
;
i
++
)
{
tw32_f
(
HOSTCC_MODE
,
tp
->
coalesce_mode
|
HOSTCC_MODE_ENABLE
|
HOSTCC_MODE_NOW
);
udelay
(
10
);
tx_idx
=
tp
->
hw_status
->
idx
[
0
].
tx_consumer
;
rx_idx
=
tp
->
hw_status
->
idx
[
0
].
rx_producer
;
if
((
tx_idx
==
send_idx
)
&&
(
rx_idx
==
(
rx_start_idx
+
num_pkts
)))
break
;
}
pci_unmap_single
(
tp
->
pdev
,
map
,
tx_len
,
PCI_DMA_TODEVICE
);
dev_kfree_skb
(
skb
);
if
(
tx_idx
!=
send_idx
)
goto
out
;
if
(
rx_idx
!=
rx_start_idx
+
num_pkts
)
goto
out
;
desc
=
&
tp
->
rx_rcb
[
rx_start_idx
];
desc_idx
=
desc
->
opaque
&
RXD_OPAQUE_INDEX_MASK
;
opaque_key
=
desc
->
opaque
&
RXD_OPAQUE_RING_MASK
;
if
(
opaque_key
!=
RXD_OPAQUE_RING_STD
)
goto
out
;
if
((
desc
->
err_vlan
&
RXD_ERR_MASK
)
!=
0
&&
(
desc
->
err_vlan
!=
RXD_ERR_ODD_NIBBLE_RCVD_MII
))
goto
out
;
rx_len
=
((
desc
->
idx_len
&
RXD_LEN_MASK
)
>>
RXD_LEN_SHIFT
)
-
4
;
if
(
rx_len
!=
tx_len
)
goto
out
;
rx_skb
=
tp
->
rx_std_buffers
[
desc_idx
].
skb
;
map
=
pci_unmap_addr
(
&
tp
->
rx_std_buffers
[
desc_idx
],
mapping
);
pci_dma_sync_single_for_cpu
(
tp
->
pdev
,
map
,
rx_len
,
PCI_DMA_FROMDEVICE
);
for
(
i
=
14
;
i
<
tx_len
;
i
++
)
{
if
(
*
(
rx_skb
->
data
+
i
)
!=
(
u8
)
(
i
&
0xff
))
goto
out
;
}
err
=
0
;
/* tg3_free_rings will unmap and free the rx_skb */
out:
return
err
;
}
static
void
tg3_self_test
(
struct
net_device
*
dev
,
struct
ethtool_test
*
etest
,
u64
*
data
)
{
struct
tg3
*
tp
=
netdev_priv
(
dev
);
memset
(
data
,
0
,
sizeof
(
u64
)
*
TG3_NUM_TEST
);
if
(
tg3_test_nvram
(
tp
)
!=
0
)
{
etest
->
flags
|=
ETH_TEST_FL_FAILED
;
data
[
0
]
=
1
;
}
if
(
tg3_test_link
(
tp
)
!=
0
)
{
etest
->
flags
|=
ETH_TEST_FL_FAILED
;
data
[
1
]
=
1
;
}
if
(
etest
->
flags
&
ETH_TEST_FL_OFFLINE
)
{
if
(
netif_running
(
dev
))
tg3_netif_stop
(
tp
);
spin_lock_irq
(
&
tp
->
lock
);
spin_lock
(
&
tp
->
tx_lock
);
tg3_halt
(
tp
,
RESET_KIND_SUSPEND
,
1
);
tg3_nvram_lock
(
tp
);
tg3_halt_cpu
(
tp
,
RX_CPU_BASE
);
if
(
!
(
tp
->
tg3_flags2
&
TG3_FLG2_5705_PLUS
))
tg3_halt_cpu
(
tp
,
TX_CPU_BASE
);
tg3_nvram_unlock
(
tp
);
if
(
tg3_test_registers
(
tp
)
!=
0
)
{
etest
->
flags
|=
ETH_TEST_FL_FAILED
;
data
[
2
]
=
1
;
}
if
(
tg3_test_memory
(
tp
)
!=
0
)
{
etest
->
flags
|=
ETH_TEST_FL_FAILED
;
data
[
3
]
=
1
;
}
if
(
tg3_test_loopback
(
tp
)
!=
0
)
{
etest
->
flags
|=
ETH_TEST_FL_FAILED
;
data
[
4
]
=
1
;
}
spin_unlock
(
&
tp
->
tx_lock
);
spin_unlock_irq
(
&
tp
->
lock
);
if
(
tg3_test_interrupt
(
tp
)
!=
0
)
{
etest
->
flags
|=
ETH_TEST_FL_FAILED
;
data
[
5
]
=
1
;
}
spin_lock_irq
(
&
tp
->
lock
);
spin_lock
(
&
tp
->
tx_lock
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
if
(
netif_running
(
dev
))
{
tp
->
tg3_flags
|=
TG3_FLAG_INIT_COMPLETE
;
tg3_init_hw
(
tp
);
tg3_netif_start
(
tp
);
}
spin_unlock
(
&
tp
->
tx_lock
);
spin_unlock_irq
(
&
tp
->
lock
);
}
}
static
int
tg3_ioctl
(
struct
net_device
*
dev
,
struct
ifreq
*
ifr
,
int
cmd
)
{
struct
mii_ioctl_data
*
data
=
if_mii
(
ifr
);
...
...
@@ -7331,6 +7870,8 @@ static struct ethtool_ops tg3_ethtool_ops = {
.
get_tso
=
ethtool_op_get_tso
,
.
set_tso
=
tg3_set_tso
,
#endif
.
self_test_count
=
tg3_get_test_count
,
.
self_test
=
tg3_self_test
,
.
get_strings
=
tg3_get_strings
,
.
get_stats_count
=
tg3_get_stats_count
,
.
get_ethtool_stats
=
tg3_get_ethtool_stats
,
...
...
@@ -9478,7 +10019,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
(
tr32
(
WDMAC_MODE
)
&
WDMAC_MODE_ENABLE
))
{
pci_save_state
(
tp
->
pdev
);
tw32
(
MEMARB_MODE
,
MEMARB_MODE_ENABLE
);
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
}
err
=
tg3_test_dma
(
tp
);
...
...
@@ -9605,7 +10146,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
spin_lock_irq
(
&
tp
->
lock
);
spin_lock
(
&
tp
->
tx_lock
);
tg3_halt
(
tp
,
1
);
tg3_halt
(
tp
,
RESET_KIND_SHUTDOWN
,
1
);
spin_unlock
(
&
tp
->
tx_lock
);
spin_unlock_irq
(
&
tp
->
lock
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录